From 9e2531b7fd758c2ae4a2f54d7e8258ca2174df9a Mon Sep 17 00:00:00 2001 From: "Simon G." Date: Wed, 1 Nov 2023 22:31:11 +0100 Subject: [PATCH] - generic parameters in ctors are now handled correctly --- LightweightIocContainer/IocContainer.cs | 34 ++++++++++++++----- .../LightweightIocContainer.xml | 5 +-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index 09ae1e3..2ab8847 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -189,7 +189,7 @@ public class IocContainer : IIocContainer, IIocResolver Type registeredType = GetType(registration); (bool result, List? parametersToResolve, NoMatchingConstructorFoundException? exception) = - TryGetTypeResolveStack(registeredType, arguments, internalResolveStack); + TryGetTypeResolveStack(registeredType, arguments, internalResolveStack); if (registration is IMultitonRegistration multitonRegistration) { @@ -483,7 +483,7 @@ public class IocContainer : IIocContainer, IIocResolver /// parameters: The parameters needed to resolve the given /// exception: A if no matching constructor was found /// - private (bool result, List? parameters, NoMatchingConstructorFoundException? exception) TryGetTypeResolveStack(Type type, IReadOnlyCollection? arguments, List resolveStack) + private (bool result, List? parameters, NoMatchingConstructorFoundException? exception) TryGetTypeResolveStack(Type type, IReadOnlyCollection? arguments, List resolveStack) { NoMatchingConstructorFoundException? noMatchingConstructorFoundException = null; @@ -491,7 +491,7 @@ public class IocContainer : IIocContainer, IIocResolver List sortedConstructors = TryGetSortedConstructors(type); foreach (ConstructorInfo constructor in sortedConstructors) { - (bool result, List? parameters, List? exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack); + (bool result, List? parameters, List? exceptions) = TryGetConstructorResolveStack(type, constructor, arguments, resolveStack); if (result) return (true, parameters, null); @@ -506,6 +506,7 @@ public class IocContainer : IIocContainer, IIocResolver /// /// Try to get the resolve stack for a given constructor /// + /// The that is currently getting resolved /// The for the given constructor /// The given arguments /// The current resolve stack @@ -514,7 +515,7 @@ public class IocContainer : IIocContainer, IIocResolver /// parameters: The parameters needed to resolve the given /// exception: A List of s if the constructor is not matching /// - private (bool result, List? parameters, List? exceptions) TryGetConstructorResolveStack(ConstructorInfo constructor, IReadOnlyCollection? arguments, List resolveStack) + private (bool result, List? parameters, List? exceptions) TryGetConstructorResolveStack(Type type, ConstructorInfo constructor, IReadOnlyCollection? arguments, List resolveStack) { List constructorParameters = constructor.GetParameters().ToList(); @@ -530,11 +531,26 @@ public class IocContainer : IIocContainer, IIocResolver object? fittingArgument = new InternalResolvePlaceholder(); if (passedArguments != null) { - fittingArgument = passedArguments.FirstOrGiven(a => - a?.GetType() == parameter.ParameterType || - parameter.ParameterType.IsInstanceOfType(a) || - a is NullParameter nullParameter && parameter.ParameterType.IsAssignableFrom(nullParameter.ParameterType)); - + if (parameter.ParameterType.IsGenericParameter) + { + Type? genericArgument = type.GetGenericArguments().FirstOrDefault(a => a.Name.Equals(parameter.ParameterType.Name)); + if (genericArgument is not null) + { + Type genericArgumentType = typeof(T).GetGenericArguments()[genericArgument.GenericParameterPosition]; + fittingArgument = passedArguments.FirstOrGiven(a => + a?.GetType() == genericArgumentType || + genericArgumentType.IsInstanceOfType(a) || + a is NullParameter nullParameter && genericArgumentType.IsAssignableFrom(nullParameter.ParameterType)); + } + } + else + { + fittingArgument = passedArguments.FirstOrGiven(a => + a?.GetType() == parameter.ParameterType || + parameter.ParameterType.IsInstanceOfType(a) || + a is NullParameter nullParameter && parameter.ParameterType.IsAssignableFrom(nullParameter.ParameterType)); + } + if (fittingArgument is not InternalResolvePlaceholder) passedArguments.Remove(fittingArgument); diff --git a/LightweightIocContainer/LightweightIocContainer.xml b/LightweightIocContainer/LightweightIocContainer.xml index a215c98..8cbfac4 100644 --- a/LightweightIocContainer/LightweightIocContainer.xml +++ b/LightweightIocContainer/LightweightIocContainer.xml @@ -1120,7 +1120,7 @@ The constructor arguments The argument list updated with the - + Try to get the resolve stack for a given @@ -1133,10 +1133,11 @@ exception: A if no matching constructor was found - + Try to get the resolve stack for a given constructor + The that is currently getting resolved The for the given constructor The given arguments The current resolve stack