diff --git a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=.00.verified.cs b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=.00.verified.cs
new file mode 100644
index 0000000..c0f90b4
--- /dev/null
+++ b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=.00.verified.cs
@@ -0,0 +1,149 @@
+//HintName: Splat.DI.Extensions.SourceGenerated.cs
+
+//
+namespace Splat
+{
+ ///
+ /// Extension methods for the Splat DI source generator.
+ ///
+ internal static partial class SplatRegistrations
+ {
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void Register()
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void Register(string contract)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void RegisterLazySingleton()
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// The threading mode.
+ public static void RegisterLazySingleton(System.Threading.LazyThreadSafetyMode mode)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void RegisterLazySingleton(string contract)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ /// The threading mode.
+ public static void RegisterLazySingleton(string contract, System.Threading.LazyThreadSafetyMode mode)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void Register()
+ {
+ }
+
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void Register(string contract)
+ {
+ }
+
+ ///
+ /// Registers a lazy class with its concrete class.
+ ///
+ public static void RegisterLazySingleton()
+ {
+ }
+
+
+ ///
+ /// Registers a lazy class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void RegisterLazySingleton(string contract)
+ {
+ }
+
+ ///
+ /// Proxy for the Splat SetService.
+ ///
+ public static void RegisterConstant(T instance) => Splat.Locator.CurrentMutable.RegisterConstant(instance);
+
+ ///
+ /// Proxy for the Splat SetService.
+ ///
+ /// Optional contract.
+ public static void RegisterConstant(T instance, string contract) => Splat.Locator.CurrentMutable.RegisterConstant(instance, contract);
+
+ ///
+ /// Registers the registrations.
+ ///
+ public static void SetupIOC()
+ {
+ SetupIOCInternal(Splat.Locator.GetLocator());
+ }
+
+ ///
+ /// Registers the registrations.
+ ///
+ /// The resolver to register with.
+ public static void SetupIOC(Splat.IDependencyResolver resolver)
+ {
+ SetupIOCInternal(resolver);
+ }
+
+
+ static partial void SetupIOCInternal(Splat.IDependencyResolver resolver);
+ }
+
+ ///
+ /// Makes the property get added by the DI engine.
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Property)]
+ internal class DependencyInjectionPropertyAttribute : System.Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DependencyInjectionPropertyAttribute()
+ {
+ }
+ }
+
+ ///
+ /// Makes this the constructor used by the DI engine.
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Constructor)]
+ internal class DependencyInjectionConstructorAttribute : System.Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DependencyInjectionConstructorAttribute()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=.01.verified.cs b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=.01.verified.cs
new file mode 100644
index 0000000..2abea93
--- /dev/null
+++ b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=.01.verified.cs
@@ -0,0 +1,19 @@
+//HintName: Splat.DI.Extensions.Registrations.SourceGenerated.cs
+
+//
+namespace Splat
+{
+ internal static partial class SplatRegistrations
+ {
+ static partial void SetupIOCInternal( Splat.IDependencyResolver resolver)
+ {
+ Splat.Locator.CurrentMutable.Register(() => new global::Test.TestConcrete((global::Test.IService1)resolver.GetService(typeof(global::Test.IService1)), (global::System.Lazy)resolver.GetService(typeof(global::System.Lazy))){ ServiceProperty1=(global::Test.IServiceProperty1)resolver.GetService(typeof(global::Test.IServiceProperty1)), ServiceProperty2=(global::Test.IServiceProperty2)resolver.GetService(typeof(global::Test.IServiceProperty2)), ServiceProperty3=(global::Test.IServiceProperty3)resolver.GetService(typeof(global::Test.IServiceProperty3))} , typeof(global::Test.ITest));
+ Splat.Locator.CurrentMutable.Register(() => new global::Test.Service1(), typeof(global::Test.IService1));
+ {
+ global::System.Lazy lazy = new global::System.Lazy(() => new global::Test.Service2());
+ Splat.Locator.CurrentMutable.Register(() => lazy, typeof(global::System.Lazy));
+ Splat.Locator.CurrentMutable.Register(() => lazy.Value, typeof(global::Test.IService2));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test1.00.verified.cs b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test1.00.verified.cs
new file mode 100644
index 0000000..c0f90b4
--- /dev/null
+++ b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test1.00.verified.cs
@@ -0,0 +1,149 @@
+//HintName: Splat.DI.Extensions.SourceGenerated.cs
+
+//
+namespace Splat
+{
+ ///
+ /// Extension methods for the Splat DI source generator.
+ ///
+ internal static partial class SplatRegistrations
+ {
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void Register()
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void Register(string contract)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void RegisterLazySingleton()
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// The threading mode.
+ public static void RegisterLazySingleton(System.Threading.LazyThreadSafetyMode mode)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void RegisterLazySingleton(string contract)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ /// The threading mode.
+ public static void RegisterLazySingleton(string contract, System.Threading.LazyThreadSafetyMode mode)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void Register()
+ {
+ }
+
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void Register(string contract)
+ {
+ }
+
+ ///
+ /// Registers a lazy class with its concrete class.
+ ///
+ public static void RegisterLazySingleton()
+ {
+ }
+
+
+ ///
+ /// Registers a lazy class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void RegisterLazySingleton(string contract)
+ {
+ }
+
+ ///
+ /// Proxy for the Splat SetService.
+ ///
+ public static void RegisterConstant(T instance) => Splat.Locator.CurrentMutable.RegisterConstant(instance);
+
+ ///
+ /// Proxy for the Splat SetService.
+ ///
+ /// Optional contract.
+ public static void RegisterConstant(T instance, string contract) => Splat.Locator.CurrentMutable.RegisterConstant(instance, contract);
+
+ ///
+ /// Registers the registrations.
+ ///
+ public static void SetupIOC()
+ {
+ SetupIOCInternal(Splat.Locator.GetLocator());
+ }
+
+ ///
+ /// Registers the registrations.
+ ///
+ /// The resolver to register with.
+ public static void SetupIOC(Splat.IDependencyResolver resolver)
+ {
+ SetupIOCInternal(resolver);
+ }
+
+
+ static partial void SetupIOCInternal(Splat.IDependencyResolver resolver);
+ }
+
+ ///
+ /// Makes the property get added by the DI engine.
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Property)]
+ internal class DependencyInjectionPropertyAttribute : System.Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DependencyInjectionPropertyAttribute()
+ {
+ }
+ }
+
+ ///
+ /// Makes this the constructor used by the DI engine.
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Constructor)]
+ internal class DependencyInjectionConstructorAttribute : System.Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DependencyInjectionConstructorAttribute()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test1.01.verified.cs b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test1.01.verified.cs
new file mode 100644
index 0000000..c3807e1
--- /dev/null
+++ b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test1.01.verified.cs
@@ -0,0 +1,19 @@
+//HintName: Splat.DI.Extensions.Registrations.SourceGenerated.cs
+
+//
+namespace Splat
+{
+ internal static partial class SplatRegistrations
+ {
+ static partial void SetupIOCInternal( Splat.IDependencyResolver resolver)
+ {
+ Splat.Locator.CurrentMutable.Register(() => new global::Test.TestConcrete((global::Test.IService1)resolver.GetService(typeof(global::Test.IService1)), (global::System.Lazy)resolver.GetService(typeof(global::System.Lazy))){ ServiceProperty1=(global::Test.IServiceProperty1)resolver.GetService(typeof(global::Test.IServiceProperty1)), ServiceProperty2=(global::Test.IServiceProperty2)resolver.GetService(typeof(global::Test.IServiceProperty2)), ServiceProperty3=(global::Test.IServiceProperty3)resolver.GetService(typeof(global::Test.IServiceProperty3))} , typeof(global::Test.ITest), "Test1");
+ Splat.Locator.CurrentMutable.Register(() => new global::Test.Service1(), typeof(global::Test.IService1), "Test1");
+ {
+ global::System.Lazy lazy = new global::System.Lazy(() => new global::Test.Service2());
+ Splat.Locator.CurrentMutable.Register(() => lazy, typeof(global::System.Lazy), "Test1");
+ Splat.Locator.CurrentMutable.Register(() => lazy.Value, typeof(global::Test.IService2), "Test1");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test2.00.verified.cs b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test2.00.verified.cs
new file mode 100644
index 0000000..c0f90b4
--- /dev/null
+++ b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test2.00.verified.cs
@@ -0,0 +1,149 @@
+//HintName: Splat.DI.Extensions.SourceGenerated.cs
+
+//
+namespace Splat
+{
+ ///
+ /// Extension methods for the Splat DI source generator.
+ ///
+ internal static partial class SplatRegistrations
+ {
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void Register()
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void Register(string contract)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void RegisterLazySingleton()
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// The threading mode.
+ public static void RegisterLazySingleton(System.Threading.LazyThreadSafetyMode mode)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void RegisterLazySingleton(string contract)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ /// The threading mode.
+ public static void RegisterLazySingleton(string contract, System.Threading.LazyThreadSafetyMode mode)
+ {
+ }
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ public static void Register()
+ {
+ }
+
+
+ ///
+ /// Registers a class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void Register(string contract)
+ {
+ }
+
+ ///
+ /// Registers a lazy class with its concrete class.
+ ///
+ public static void RegisterLazySingleton()
+ {
+ }
+
+
+ ///
+ /// Registers a lazy class with its concrete class.
+ ///
+ /// Optional contract.
+ public static void RegisterLazySingleton(string contract)
+ {
+ }
+
+ ///
+ /// Proxy for the Splat SetService.
+ ///
+ public static void RegisterConstant(T instance) => Splat.Locator.CurrentMutable.RegisterConstant(instance);
+
+ ///
+ /// Proxy for the Splat SetService.
+ ///
+ /// Optional contract.
+ public static void RegisterConstant(T instance, string contract) => Splat.Locator.CurrentMutable.RegisterConstant(instance, contract);
+
+ ///
+ /// Registers the registrations.
+ ///
+ public static void SetupIOC()
+ {
+ SetupIOCInternal(Splat.Locator.GetLocator());
+ }
+
+ ///
+ /// Registers the registrations.
+ ///
+ /// The resolver to register with.
+ public static void SetupIOC(Splat.IDependencyResolver resolver)
+ {
+ SetupIOCInternal(resolver);
+ }
+
+
+ static partial void SetupIOCInternal(Splat.IDependencyResolver resolver);
+ }
+
+ ///
+ /// Makes the property get added by the DI engine.
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Property)]
+ internal class DependencyInjectionPropertyAttribute : System.Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DependencyInjectionPropertyAttribute()
+ {
+ }
+ }
+
+ ///
+ /// Makes this the constructor used by the DI engine.
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Constructor)]
+ internal class DependencyInjectionConstructorAttribute : System.Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DependencyInjectionConstructorAttribute()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test2.01.verified.cs b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test2.01.verified.cs
new file mode 100644
index 0000000..7226579
--- /dev/null
+++ b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.LazyParameterRegisteredLazy_contract=Test2.01.verified.cs
@@ -0,0 +1,19 @@
+//HintName: Splat.DI.Extensions.Registrations.SourceGenerated.cs
+
+//
+namespace Splat
+{
+ internal static partial class SplatRegistrations
+ {
+ static partial void SetupIOCInternal( Splat.IDependencyResolver resolver)
+ {
+ Splat.Locator.CurrentMutable.Register(() => new global::Test.TestConcrete((global::Test.IService1)resolver.GetService(typeof(global::Test.IService1)), (global::System.Lazy)resolver.GetService(typeof(global::System.Lazy))){ ServiceProperty1=(global::Test.IServiceProperty1)resolver.GetService(typeof(global::Test.IServiceProperty1)), ServiceProperty2=(global::Test.IServiceProperty2)resolver.GetService(typeof(global::Test.IServiceProperty2)), ServiceProperty3=(global::Test.IServiceProperty3)resolver.GetService(typeof(global::Test.IServiceProperty3))} , typeof(global::Test.ITest), "Test2");
+ Splat.Locator.CurrentMutable.Register(() => new global::Test.Service1(), typeof(global::Test.IService1), "Test2");
+ {
+ global::System.Lazy lazy = new global::System.Lazy(() => new global::Test.Service2());
+ Splat.Locator.CurrentMutable.Register(() => lazy, typeof(global::System.Lazy), "Test2");
+ Splat.Locator.CurrentMutable.Register(() => lazy.Value, typeof(global::Test.IService2), "Test2");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.cs b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.cs
index b4c0485..6fd0b11 100644
--- a/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.cs
+++ b/src/Splat.DependencyInjection.SourceGenerator.Tests/RegisterLazySingletonTests.cs
@@ -83,5 +83,67 @@ public interface IServiceProperty3 {{ }}
return TestPass(source, contract, mode);
}
+
+ [Theory]
+ [InlineData("")]
+ [InlineData("Test1")]
+ [InlineData("Test2")]
+ public Task LazyParameterRegisteredLazy(string contract)
+ {
+ string arguments;
+ if (string.IsNullOrWhiteSpace(contract))
+ {
+ arguments = string.Empty;
+ }
+ else
+ {
+ arguments = $"\"{contract}\"";
+ }
+
+ var source = @$"
+using System;
+using System.Threading;
+using Splat;
+
+namespace Test
+{{
+ public static class DIRegister
+ {{
+ static DIRegister()
+ {{
+ SplatRegistrations.Register({arguments});
+ SplatRegistrations.Register({arguments});
+ SplatRegistrations.RegisterLazySingleton({arguments});
+ }}
+ }}
+
+ public interface ITest {{ }}
+ public class TestConcrete : ITest
+ {{
+ public TestConcrete(IService1 service1, Lazy service)
+ {{
+ }}
+
+ [DependencyInjectionProperty]
+ public IServiceProperty1 ServiceProperty1 {{ get; set; }}
+
+ [DependencyInjectionProperty]
+ public IServiceProperty2 ServiceProperty2 {{ get; set; }}
+
+ [DependencyInjectionProperty]
+ internal IServiceProperty3 ServiceProperty3 {{ get; set; }}
+ }}
+
+ public interface IService1 {{ }}
+ public class Service1 : IService1 {{ }}
+ public interface IService2 {{ }}
+ public class Service2 : IService2 {{ }}
+ public interface IServiceProperty1 {{ }}
+ public interface IServiceProperty2 {{ }}
+ public interface IServiceProperty3 {{ }}
+}}";
+
+ return TestPass(source, contract);
+ }
}
}
diff --git a/src/Splat.DependencyInjection.SourceGenerator/MetadataDependencyChecker.cs b/src/Splat.DependencyInjection.SourceGenerator/MetadataDependencyChecker.cs
index 259bd49..c38247d 100644
--- a/src/Splat.DependencyInjection.SourceGenerator/MetadataDependencyChecker.cs
+++ b/src/Splat.DependencyInjection.SourceGenerator/MetadataDependencyChecker.cs
@@ -49,7 +49,10 @@ public static List CheckMetadata(GeneratorExecutionContext conte
{
if (childConstructor.TypeName == metadataMethod.InterfaceTypeName)
{
- throw new ContextDiagnosticException(Diagnostic.Create(DiagnosticWarnings.ConstructorsMustNotHaveCircularDependency, childConstructor.Parameter.Locations.FirstOrDefault() ?? metadataMethod.MethodInvocation.GetLocation()));
+ throw new ContextDiagnosticException(
+ Diagnostic.Create(
+ DiagnosticWarnings.ConstructorsMustNotHaveCircularDependency,
+ childConstructor.Parameter.Locations.FirstOrDefault() ?? metadataMethod.MethodInvocation.GetLocation()));
}
}
}
@@ -67,7 +70,15 @@ public static List CheckMetadata(GeneratorExecutionContext conte
if (metadataDependencies.TryGetValue(lazyType.ToDisplayString(RoslynCommonHelpers.TypeFormat), out dependencyMethod))
{
- throw new ContextDiagnosticException(Diagnostic.Create(DiagnosticWarnings.LazyParameterNotRegisteredLazy, constructorDependency.Parameter.Locations.FirstOrDefault() ?? metadataMethod.MethodInvocation.GetLocation(), metadataMethod.ConcreteTypeName, constructorDependency.Parameter.Name));
+ if (!dependencyMethod.IsLazy)
+ {
+ throw new ContextDiagnosticException(
+ Diagnostic.Create(
+ DiagnosticWarnings.LazyParameterNotRegisteredLazy,
+ constructorDependency.Parameter.Locations.FirstOrDefault() ?? metadataMethod.MethodInvocation.GetLocation(),
+ metadataMethod.ConcreteTypeName,
+ constructorDependency.Parameter.Name));
+ }
}
}
}