From 1d3b841789c822decde4a122d31d4f1e3e3dd4b7 Mon Sep 17 00:00:00 2001 From: Alon Talmi Date: Tue, 14 Nov 2023 13:37:14 +0100 Subject: [PATCH 1/2] Added option to lazily create paramaters and use the scope's resolver Discard unused resolver parameter --- .../VContainer/Runtime/IInjectParameter.cs | 2 +- .../Runtime/IObjectResolverExtensions.cs | 2 +- .../Runtime/Internal/InjectParameter.cs | 52 ++++++++++++++++++- .../VContainer/Runtime/RegistrationBuilder.cs | 24 +++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/VContainer/Assets/VContainer/Runtime/IInjectParameter.cs b/VContainer/Assets/VContainer/Runtime/IInjectParameter.cs index 676faca2..337dd2a8 100644 --- a/VContainer/Assets/VContainer/Runtime/IInjectParameter.cs +++ b/VContainer/Assets/VContainer/Runtime/IInjectParameter.cs @@ -5,6 +5,6 @@ namespace VContainer public interface IInjectParameter { bool Match(Type parameterType, string parameterName); - object Value { get; } + object GetValue(IObjectResolver resolver); } } \ No newline at end of file diff --git a/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs b/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs index ed87fe97..cd3b15be 100644 --- a/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs +++ b/VContainer/Assets/VContainer/Runtime/IObjectResolverExtensions.cs @@ -28,7 +28,7 @@ public static object ResolveOrParameter( var parameter = parameters[i]; if (parameter.Match(parameterType, parameterName)) { - return parameter.Value; + return parameter.GetValue(resolver); } } } diff --git a/VContainer/Assets/VContainer/Runtime/Internal/InjectParameter.cs b/VContainer/Assets/VContainer/Runtime/Internal/InjectParameter.cs index f90395e5..07a0cfcf 100644 --- a/VContainer/Assets/VContainer/Runtime/Internal/InjectParameter.cs +++ b/VContainer/Assets/VContainer/Runtime/Internal/InjectParameter.cs @@ -5,7 +5,7 @@ namespace VContainer.Internal sealed class TypedParameter : IInjectParameter { public readonly Type Type; - public object Value { get; } + public readonly object Value; public TypedParameter(Type type, object value) { @@ -14,12 +14,36 @@ public TypedParameter(Type type, object value) } public bool Match(Type parameterType, string _) => parameterType == Type; + + public object GetValue(IObjectResolver _) + { + return Value; + } + } + + sealed class FuncTypedParameter : IInjectParameter + { + public readonly Type Type; + public readonly Func Func; + + public FuncTypedParameter(Type type, Func func) + { + Type = type; + Func = func; + } + + public bool Match(Type parameterType, string _) => parameterType == Type; + + public object GetValue(IObjectResolver resolver) + { + return Func(resolver); + } } sealed class NamedParameter : IInjectParameter { public readonly string Name; - public object Value { get; } + public readonly object Value; public NamedParameter(string name, object value) { @@ -28,5 +52,29 @@ public NamedParameter(string name, object value) } public bool Match(Type _, string parameterName) => parameterName == Name; + + public object GetValue(IObjectResolver _) + { + return Value; + } + } + + sealed class FuncNamedParameter : IInjectParameter + { + public readonly string Name; + public readonly Func Func; + + public FuncNamedParameter(string name, Func func) + { + Name = name; + Func = func; + } + + public bool Match(Type _, string parameterName) => parameterName == Name; + + public object GetValue(IObjectResolver resolver) + { + return Func(resolver); + } } } diff --git a/VContainer/Assets/VContainer/Runtime/RegistrationBuilder.cs b/VContainer/Assets/VContainer/Runtime/RegistrationBuilder.cs index ace303b2..4f59a0a1 100644 --- a/VContainer/Assets/VContainer/Runtime/RegistrationBuilder.cs +++ b/VContainer/Assets/VContainer/Runtime/RegistrationBuilder.cs @@ -90,6 +90,13 @@ public RegistrationBuilder WithParameter(string name, object value) Parameters.Add(new NamedParameter(name, value)); return this; } + + public RegistrationBuilder WithParameter(string name, Func value) + { + Parameters = Parameters ?? new List(); + Parameters.Add(new FuncNamedParameter(name, value)); + return this; + } public RegistrationBuilder WithParameter(Type type, object value) { @@ -97,11 +104,28 @@ public RegistrationBuilder WithParameter(Type type, object value) Parameters.Add(new TypedParameter(type, value)); return this; } + + public RegistrationBuilder WithParameter(Type type, Func value) + { + Parameters = Parameters ?? new List(); + Parameters.Add(new FuncTypedParameter(type, value)); + return this; + } public RegistrationBuilder WithParameter(TParam value) { return WithParameter(typeof(TParam), value); } + + public RegistrationBuilder WithParameter(Func value) + { + return WithParameter(typeof(TParam), resolver => value(resolver)); + } + + public RegistrationBuilder WithParameter(Func value) + { + return WithParameter(typeof(TParam), _ => value()); + } protected virtual void AddInterfaceType(Type interfaceType) { From a8a6315bd2b6b5eddf83bae48349d15596034d86 Mon Sep 17 00:00:00 2001 From: Alon Talmi Date: Wed, 15 Nov 2023 09:08:40 +0100 Subject: [PATCH 2/2] Added WithParameter with resolver UnitTests --- VContainer/Assets/Tests/ContainerTest.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/VContainer/Assets/Tests/ContainerTest.cs b/VContainer/Assets/Tests/ContainerTest.cs index 421d6a0f..9ef82f78 100644 --- a/VContainer/Assets/Tests/ContainerTest.cs +++ b/VContainer/Assets/Tests/ContainerTest.cs @@ -429,6 +429,17 @@ public void RegisterWithParameter() var resolved = container.Resolve(); Assert.That(resolved.Service2, Is.EqualTo(paramValue)); } + + { + var builder = new ContainerBuilder(); + builder.Register(Lifetime.Scoped); + builder.Register(Lifetime.Scoped) + .WithParameter(resolver => resolver.Resolve()); + + var container = builder.Build(); + var resolved = container.Resolve(); + Assert.That(resolved.Service2, Is.Not.Null); + } } [Test]