diff --git a/src/Immediate.Injections.Analyzers/RegisterTypeAnalyzer.cs b/src/Immediate.Injections.Analyzers/RegisterTypeAnalyzer.cs index 0f2b086..9e0dadd 100644 --- a/src/Immediate.Injections.Analyzers/RegisterTypeAnalyzer.cs +++ b/src/Immediate.Injections.Analyzers/RegisterTypeAnalyzer.cs @@ -303,6 +303,34 @@ public bool AnalyzeRegisterType0Attribute() valid = false; } } + else if (containerSymbol.IsGenericType) + { + if (useProxy) + { + context.ReportDiagnostic( + Diagnostic.Create( + RegisterTypeAnalyzer.CannotUseProxyFactoryForOpenGeneric, + location, + containerSymbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat) + ) + ); + + valid = false; + } + + if (factory is { }) + { + context.ReportDiagnostic( + Diagnostic.Create( + RegisterTypeAnalyzer.CannotUseFactoryMethodWithOpenGeneric, + location, + containerSymbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat) + ) + ); + + valid = false; + } + } switch (registrationStrategy) { diff --git a/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0008.cs b/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0008.cs index bc71962..b7c6d68 100644 --- a/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0008.cs +++ b/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0008.cs @@ -16,4 +16,84 @@ public interface IService; public class Class : IService; """ ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task UseProxyFactoryWithInferredOpenGenericSelfStrategyTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using Immediate.Injections.Shared; + + [{|INJ0007:{|INJ0008:{|INJ0002:RegisterSingleton(RegistrationStrategy = RegistrationStrategy.Self, UseProxyFactory = true)|}|}|}] + public class Class; + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task UseProxyFactoryWithInferredOpenGenericImplementedInterfacesStrategyTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using Immediate.Injections.Shared; + + public interface IService; + + [{|INJ0008:{|INJ0002:RegisterSingleton(RegistrationStrategy = RegistrationStrategy.ImplementedInterfaces, UseProxyFactory = true)|}|}] + public class Class : IService; + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task UseProxyFactoryWithInferredOpenGenericSelfAndImplementedInterfacesStrategyTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using Immediate.Injections.Shared; + + public interface IService; + + [{|INJ0008:{|INJ0002:RegisterSingleton(RegistrationStrategy = RegistrationStrategy.SelfAndImplementedInterfaces, UseProxyFactory = true)|}|}] + public class Class : IService; + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task UseProxyFactoryWithAssemblyDefaultInferredOpenGenericTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using Immediate.Injections.Shared; + + [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.ImplementedInterfaces)] + + public interface IService; + + [{|INJ0008:{|INJ0002:RegisterSingleton(UseProxyFactory = true)|}|}] + public class Class : IService; + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task UseProxyFactoryWithAssemblyDefaultSelfInferredOpenGenericTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using Immediate.Injections.Shared; + + [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.Self)] + + [{|INJ0007:{|INJ0008:{|INJ0002:RegisterSingleton(UseProxyFactory = true)|}|}|}] + public class Class; + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task UseProxyFactoryWithAssemblyDefaultSelfAndImplementedInterfacesInferredOpenGenericTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using Immediate.Injections.Shared; + + [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.SelfAndImplementedInterfaces)] + + public interface IService; + + [{|INJ0008:{|INJ0002:RegisterSingleton(UseProxyFactory = true)|}|}] + public class Class : IService; + """ + ).RunAsync(TestContext.Current.CancellationToken); } diff --git a/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0012.cs b/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0012.cs index f7f2bdb..65b2051 100644 --- a/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0012.cs +++ b/tests/Immediate.Injections.Tests/AnalyzerTests/RegisterTypeAnalyzerTests.INJ0012.cs @@ -21,4 +21,114 @@ public class Class : IService } """ ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task FactoryMethodWithInferredOpenGenericSelfStrategyTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using System; + + using Immediate.Injections.Shared; + + [{|INJ0012:{|INJ0002:RegisterSingleton(RegistrationStrategy = RegistrationStrategy.Self, Factory = nameof(Factory))|}|}] + public class Class + { + public static Class Factory(IServiceProvider provider) => new(); + } + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task FactoryMethodWithInferredOpenGenericImplementedInterfacesStrategyTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using System; + + using Immediate.Injections.Shared; + + public interface IService; + + [{|INJ0012:{|INJ0002:RegisterSingleton(RegistrationStrategy = RegistrationStrategy.ImplementedInterfaces, Factory = nameof(Factory))|}|}] + public class Class : IService + { + public static Class Factory(IServiceProvider provider) => new(); + } + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task FactoryMethodWithInferredOpenGenericSelfAndImplementedInterfacesStrategyTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using System; + + using Immediate.Injections.Shared; + + public interface IService; + + [{|INJ0012:{|INJ0002:RegisterSingleton(RegistrationStrategy = RegistrationStrategy.SelfAndImplementedInterfaces, Factory = nameof(Factory))|}|}] + public class Class : IService + { + public static Class Factory(IServiceProvider provider) => new(); + } + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task FactoryMethodWithAssemblyDefaultInferredOpenGenericTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using System; + + using Immediate.Injections.Shared; + + [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.ImplementedInterfaces)] + + public interface IService; + + [{|INJ0012:{|INJ0002:RegisterSingleton(Factory = nameof(Factory))|}|}] + public class Class : IService + { + public static Class Factory(IServiceProvider provider) => new(); + } + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task FactoryMethodWithAssemblyDefaultSelfInferredOpenGenericTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using System; + + using Immediate.Injections.Shared; + + [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.Self)] + + [{|INJ0012:{|INJ0002:RegisterSingleton(Factory = nameof(Factory))|}|}] + public class Class + { + public static Class Factory(IServiceProvider provider) => new(); + } + """ + ).RunAsync(TestContext.Current.CancellationToken); + + [Fact] + public async Task FactoryMethodWithAssemblyDefaultSelfAndImplementedInterfacesInferredOpenGenericTriggers() => + await AnalyzerTestHelpers.CreateAnalyzerTest( + """ + using System; + + using Immediate.Injections.Shared; + + [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.SelfAndImplementedInterfaces)] + + public interface IService; + + [{|INJ0012:{|INJ0002:RegisterSingleton(Factory = nameof(Factory))|}|}] + public class Class : IService + { + public static Class Factory(IServiceProvider provider) => new(); + } + """ + ).RunAsync(TestContext.Current.CancellationToken); }