- generic parameters in ctors are now handled correctly

ImplementExpressionTrees v4.3.0
Simon G. 2 years ago
parent 8102db3f77
commit 9e2531b7fd
Signed by: SimonG
GPG Key ID: 7CD6DBFB1B2786ED
  1. 32
      LightweightIocContainer/IocContainer.cs
  2. 5
      LightweightIocContainer/LightweightIocContainer.xml

@ -189,7 +189,7 @@ public class IocContainer : IIocContainer, IIocResolver
Type registeredType = GetType<T>(registration); Type registeredType = GetType<T>(registration);
(bool result, List<object?>? parametersToResolve, NoMatchingConstructorFoundException? exception) = (bool result, List<object?>? parametersToResolve, NoMatchingConstructorFoundException? exception) =
TryGetTypeResolveStack(registeredType, arguments, internalResolveStack); TryGetTypeResolveStack<T>(registeredType, arguments, internalResolveStack);
if (registration is IMultitonRegistration multitonRegistration) if (registration is IMultitonRegistration multitonRegistration)
{ {
@ -483,7 +483,7 @@ public class IocContainer : IIocContainer, IIocResolver
/// <para>parameters: The parameters needed to resolve the given <see cref="Type"/></para> /// <para>parameters: The parameters needed to resolve the given <see cref="Type"/></para>
/// <para>exception: A <see cref="NoMatchingConstructorFoundException"/> if no matching constructor was found</para> /// <para>exception: A <see cref="NoMatchingConstructorFoundException"/> if no matching constructor was found</para>
/// </returns> /// </returns>
private (bool result, List<object?>? parameters, NoMatchingConstructorFoundException? exception) TryGetTypeResolveStack(Type type, IReadOnlyCollection<object?>? arguments, List<Type> resolveStack) private (bool result, List<object?>? parameters, NoMatchingConstructorFoundException? exception) TryGetTypeResolveStack<T>(Type type, IReadOnlyCollection<object?>? arguments, List<Type> resolveStack)
{ {
NoMatchingConstructorFoundException? noMatchingConstructorFoundException = null; NoMatchingConstructorFoundException? noMatchingConstructorFoundException = null;
@ -491,7 +491,7 @@ public class IocContainer : IIocContainer, IIocResolver
List<ConstructorInfo> sortedConstructors = TryGetSortedConstructors(type); List<ConstructorInfo> sortedConstructors = TryGetSortedConstructors(type);
foreach (ConstructorInfo constructor in sortedConstructors) foreach (ConstructorInfo constructor in sortedConstructors)
{ {
(bool result, List<object?>? parameters, List<ConstructorNotMatchingException>? exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack); (bool result, List<object?>? parameters, List<ConstructorNotMatchingException>? exceptions) = TryGetConstructorResolveStack<T>(type, constructor, arguments, resolveStack);
if (result) if (result)
return (true, parameters, null); return (true, parameters, null);
@ -506,6 +506,7 @@ public class IocContainer : IIocContainer, IIocResolver
/// <summary> /// <summary>
/// Try to get the resolve stack for a given constructor /// Try to get the resolve stack for a given constructor
/// </summary> /// </summary>
/// <param name="type">The <see cref="Type"/> that is currently getting resolved</param>
/// <param name="constructor">The <see cref="ConstructorInfo"/> for the given constructor</param> /// <param name="constructor">The <see cref="ConstructorInfo"/> for the given constructor</param>
/// <param name="arguments">The given arguments</param> /// <param name="arguments">The given arguments</param>
/// <param name="resolveStack">The current resolve stack</param> /// <param name="resolveStack">The current resolve stack</param>
@ -514,7 +515,7 @@ public class IocContainer : IIocContainer, IIocResolver
/// <para>parameters: The parameters needed to resolve the given <see cref="Type"/></para> /// <para>parameters: The parameters needed to resolve the given <see cref="Type"/></para>
/// <para>exception: A List of <see cref="ConstructorNotMatchingException"/>s if the constructor is not matching</para> /// <para>exception: A List of <see cref="ConstructorNotMatchingException"/>s if the constructor is not matching</para>
/// </returns> /// </returns>
private (bool result, List<object?>? parameters, List<ConstructorNotMatchingException>? exceptions) TryGetConstructorResolveStack(ConstructorInfo constructor, IReadOnlyCollection<object?>? arguments, List<Type> resolveStack) private (bool result, List<object?>? parameters, List<ConstructorNotMatchingException>? exceptions) TryGetConstructorResolveStack<T>(Type type, ConstructorInfo constructor, IReadOnlyCollection<object?>? arguments, List<Type> resolveStack)
{ {
List<ParameterInfo> constructorParameters = constructor.GetParameters().ToList(); List<ParameterInfo> constructorParameters = constructor.GetParameters().ToList();
@ -530,10 +531,25 @@ public class IocContainer : IIocContainer, IIocResolver
object? fittingArgument = new InternalResolvePlaceholder(); object? fittingArgument = new InternalResolvePlaceholder();
if (passedArguments != null) if (passedArguments != null)
{ {
fittingArgument = passedArguments.FirstOrGiven<object?, InternalResolvePlaceholder>(a => if (parameter.ParameterType.IsGenericParameter)
a?.GetType() == parameter.ParameterType || {
parameter.ParameterType.IsInstanceOfType(a) || Type? genericArgument = type.GetGenericArguments().FirstOrDefault(a => a.Name.Equals(parameter.ParameterType.Name));
a is NullParameter nullParameter && parameter.ParameterType.IsAssignableFrom(nullParameter.ParameterType)); if (genericArgument is not null)
{
Type genericArgumentType = typeof(T).GetGenericArguments()[genericArgument.GenericParameterPosition];
fittingArgument = passedArguments.FirstOrGiven<object?, InternalResolvePlaceholder>(a =>
a?.GetType() == genericArgumentType ||
genericArgumentType.IsInstanceOfType(a) ||
a is NullParameter nullParameter && genericArgumentType.IsAssignableFrom(nullParameter.ParameterType));
}
}
else
{
fittingArgument = passedArguments.FirstOrGiven<object?, InternalResolvePlaceholder>(a =>
a?.GetType() == parameter.ParameterType ||
parameter.ParameterType.IsInstanceOfType(a) ||
a is NullParameter nullParameter && parameter.ParameterType.IsAssignableFrom(nullParameter.ParameterType));
}
if (fittingArgument is not InternalResolvePlaceholder) if (fittingArgument is not InternalResolvePlaceholder)
passedArguments.Remove(fittingArgument); passedArguments.Remove(fittingArgument);

@ -1120,7 +1120,7 @@
<param name="arguments">The constructor arguments</param> <param name="arguments">The constructor arguments</param>
<returns>The argument list updated with the <see cref="P:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithParametersInternal.Parameters"/></returns> <returns>The argument list updated with the <see cref="P:LightweightIocContainer.Interfaces.Registrations.Fluent.IWithParametersInternal.Parameters"/></returns>
</member> </member>
<member name="M:LightweightIocContainer.IocContainer.TryGetTypeResolveStack(System.Type,System.Collections.Generic.IReadOnlyCollection{System.Object},System.Collections.Generic.List{System.Type})"> <member name="M:LightweightIocContainer.IocContainer.TryGetTypeResolveStack``1(System.Type,System.Collections.Generic.IReadOnlyCollection{System.Object},System.Collections.Generic.List{System.Type})">
<summary> <summary>
Try to get the resolve stack for a given <see cref="T:System.Type"/> Try to get the resolve stack for a given <see cref="T:System.Type"/>
</summary> </summary>
@ -1133,10 +1133,11 @@
<para>exception: A <see cref="T:LightweightIocContainer.Exceptions.NoMatchingConstructorFoundException"/> if no matching constructor was found</para> <para>exception: A <see cref="T:LightweightIocContainer.Exceptions.NoMatchingConstructorFoundException"/> if no matching constructor was found</para>
</returns> </returns>
</member> </member>
<member name="M:LightweightIocContainer.IocContainer.TryGetConstructorResolveStack(System.Reflection.ConstructorInfo,System.Collections.Generic.IReadOnlyCollection{System.Object},System.Collections.Generic.List{System.Type})"> <member name="M:LightweightIocContainer.IocContainer.TryGetConstructorResolveStack``1(System.Type,System.Reflection.ConstructorInfo,System.Collections.Generic.IReadOnlyCollection{System.Object},System.Collections.Generic.List{System.Type})">
<summary> <summary>
Try to get the resolve stack for a given constructor Try to get the resolve stack for a given constructor
</summary> </summary>
<param name="type">The <see cref="T:System.Type"/> that is currently getting resolved</param>
<param name="constructor">The <see cref="T:System.Reflection.ConstructorInfo"/> for the given constructor</param> <param name="constructor">The <see cref="T:System.Reflection.ConstructorInfo"/> for the given constructor</param>
<param name="arguments">The given arguments</param> <param name="arguments">The given arguments</param>
<param name="resolveStack">The current resolve stack</param> <param name="resolveStack">The current resolve stack</param>

Loading…
Cancel
Save