Skip to content

Commit

Permalink
Don't report inconsitencies if lifetimes match
Browse files Browse the repository at this point in the history
We automatically deduplicate service registrations that are exactly the same, so we don't need to report that case.
  • Loading branch information
kzu committed Dec 6, 2024
1 parent fa1b5bd commit 0517d5e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
54 changes: 54 additions & 0 deletions src/CodeAnalysis.Tests/ConventionAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,58 @@ public static void Main()

await test.RunAsync();
}

[Fact]
public async Task NoWarnIfMultipleSameLifetime()
{
var test = new CSharpSourceGeneratorTest<IncrementalGenerator, DefaultVerifier>
{
TestBehaviors = TestBehaviors.SkipGeneratedSourcesCheck,
TestCode =
"""
using System;
using Microsoft.Extensions.DependencyInjection;
public interface IRepository { }
[Service]
public class MyRepository : IRepository { }
public static class Program
{
public static void Main()
{
var services = new ServiceCollection();
services.AddServices(typeof(IRepository));
}
}
""",
TestState =
{
AnalyzerConfigFiles =
{
("/.editorconfig",
"""
is_global = true
build_property.AddServicesExtension = true
""")
},
Sources =
{
StaticGenerator.AddServicesExtension,
StaticGenerator.ServiceAttribute,
StaticGenerator.ServiceAttributeT,
},
ReferenceAssemblies = new ReferenceAssemblies(
"net8.0",
new PackageIdentity(
"Microsoft.NETCore.App.Ref", "8.0.0"),
Path.Combine("ref", "net8.0"))
.AddPackages(ImmutableArray.Create(
new PackageIdentity("Microsoft.Extensions.DependencyInjection", "8.0.0")))
},
};

await test.RunAsync();
}
}
2 changes: 2 additions & 0 deletions src/DependencyInjection.Tests/GenerationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,9 @@ public class SmsNotificationService : INotificationService

// Showcases that legacy generic Service<TKey> attribute still works
[Service("email")]
#pragma warning disable CS0618 // Type or member is obsolete
[Service<string>("default")]
#pragma warning restore CS0618 // Type or member is obsolete
public class EmailNotificationService : INotificationService
{
public string Notify(string message) => $"[Email] {message}";
Expand Down
10 changes: 7 additions & 3 deletions src/DependencyInjection/IncrementalGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,14 +283,18 @@ void ReportInconsistencies(SourceProductionContext context, ImmutableArray<Servi
// report if within the group, there are different lifetimes with the same key (or no key)
foreach (var keyed in group.GroupBy(x => x.Key?.Value).Where(g => g.Count() > 1))
{
var lifetimes = string.Join(", ", keyed.Select(x => x.Lifetime).Distinct()
.Select(x => x switch { 0 => "Singleton", 1 => "Scoped", 2 => "Transient", _ => "Unknown" }));
var lifetimes = keyed.Select(x => x.Lifetime).Distinct()
.Select(x => x switch { 0 => "Singleton", 1 => "Scoped", 2 => "Transient", _ => "Unknown" })
.ToArray();

if (lifetimes.Length == 1)
continue;

var location = keyed.Where(x => x.Location != null).FirstOrDefault()?.Location;
var otherLocations = keyed.Where(x => x.Location != null).Skip(1).Select(x => x.Location!);

context.ReportDiagnostic(Diagnostic.Create(AmbiguousLifetime,
location, otherLocations, keyed.First().Type.ToDisplayString(), lifetimes));
location, otherLocations, keyed.First().Type.ToDisplayString(), string.Join(", ", lifetimes)));
}
}
}
Expand Down

0 comments on commit 0517d5e

Please sign in to comment.