#51: extract tryGetTypeResolveStack() method

pull/57/head
Simon G 4 years ago
parent 6687bdb8b4
commit 7bab6bccda
  1. 70
      LightweightIocContainer/IocContainer.cs
  2. 5
      Test.LightweightIocContainer/IocContainerRecursionTest.cs

@ -486,6 +486,33 @@ namespace LightweightIocContainer
/// <exception cref="NoMatchingConstructorFoundException">No matching constructor was found for the given or resolvable arguments</exception> /// <exception cref="NoMatchingConstructorFoundException">No matching constructor was found for the given or resolvable arguments</exception>
[CanBeNull] [CanBeNull]
private object[] ResolveTypeCreationArguments(Type type, object[] arguments, List<Type> resolveStack) private object[] ResolveTypeCreationArguments(Type type, object[] arguments, List<Type> resolveStack)
{
(bool result, List<object> parameters, NoMatchingConstructorFoundException exception) = TryGetTypeResolveStack(type, arguments, resolveStack);
if (result)
{
if (parameters == null)
return null;
List<object> constructorParameters = new();
foreach (object parameter in parameters)
{
if (parameter is InternalToBeResolvedPlaceholder toBeResolvedPlaceholder)
constructorParameters.Add(Resolve(toBeResolvedPlaceholder, resolveStack));
else
constructorParameters.Add(parameter);
}
return constructorParameters.ToArray();
}
if (exception != null)
throw exception;
return null;
}
private (bool result, List<object> parameters, NoMatchingConstructorFoundException exception) TryGetTypeResolveStack(Type type, object[] arguments, List<Type> resolveStack)
{ {
NoMatchingConstructorFoundException noMatchingConstructorFoundException = null; NoMatchingConstructorFoundException noMatchingConstructorFoundException = null;
@ -496,31 +523,14 @@ namespace LightweightIocContainer
(bool result, List<object> parameters, List<ConstructorNotMatchingException> exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack); (bool result, List<object> parameters, List<ConstructorNotMatchingException> exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack);
if (result) if (result)
{ return (true, parameters, null);
if (parameters == null)
return null;
List<object> constructorParameters = new();
foreach (object parameter in parameters)
{
if (parameter is InternalToBeResolvedPlaceholder toBeResolvedPlaceholder)
constructorParameters.Add(Resolve(toBeResolvedPlaceholder, resolveStack));
else
constructorParameters.Add(parameter);
}
return constructorParameters.ToArray();
}
noMatchingConstructorFoundException ??= new NoMatchingConstructorFoundException(type); noMatchingConstructorFoundException ??= new NoMatchingConstructorFoundException(type);
exceptions.ForEach(e => exceptions?.ForEach(e =>
noMatchingConstructorFoundException.AddInnerException(new ConstructorNotMatchingException(constructor, e))); noMatchingConstructorFoundException.AddInnerException(new ConstructorNotMatchingException(constructor, e)));
} }
if (noMatchingConstructorFoundException != null) return (false, null, noMatchingConstructorFoundException);
throw noMatchingConstructorFoundException;
return null;
} }
private (bool result, List<object> parameters, List<ConstructorNotMatchingException> constructorNotMatchingExceptions) TryGetConstructorResolveStack(ConstructorInfo constructor, object[] arguments, List<Type> resolveStack) private (bool result, List<object> parameters, List<ConstructorNotMatchingException> constructorNotMatchingExceptions) TryGetConstructorResolveStack(ConstructorInfo constructor, object[] arguments, List<Type> resolveStack)
@ -555,7 +565,7 @@ namespace LightweightIocContainer
IRegistration registration = FindRegistration(parameter.ParameterType) ?? throw new TypeNotRegisteredException(parameter.ParameterType); IRegistration registration = FindRegistration(parameter.ParameterType) ?? throw new TypeNotRegisteredException(parameter.ParameterType);
List<Type> internalResolveStack = new(resolveStack); List<Type> internalResolveStack = new(resolveStack);
internalResolveStack = CheckForCircularDependencies(parameter.ParameterType, internalResolveStack); //testMe: seems to work internalResolveStack = CheckForCircularDependencies(parameter.ParameterType, internalResolveStack);
Type registeredType = GetTypeNonGeneric(parameter.ParameterType, registration); Type registeredType = GetTypeNonGeneric(parameter.ParameterType, registration);
@ -568,19 +578,13 @@ namespace LightweightIocContainer
if (registration is IWithParametersInternal { Parameters: { } } registrationWithParameters) if (registration is IWithParametersInternal { Parameters: { } } registrationWithParameters)
argumentsForRegistration = UpdateArgumentsWithRegistrationParameters(registrationWithParameters, null); argumentsForRegistration = UpdateArgumentsWithRegistrationParameters(registrationWithParameters, null);
foreach (ConstructorInfo registeredTypeConstructor in TryGetSortedConstructors(registeredType)) (bool result, List<object> parametersToResolve, NoMatchingConstructorFoundException exception) =
{ TryGetTypeResolveStack(registeredType, argumentsForRegistration, internalResolveStack);
(bool result, List<object> parametersToResolve, List<ConstructorNotMatchingException> exceptions) =
TryGetConstructorResolveStack(registeredTypeConstructor, argumentsForRegistration, internalResolveStack);
if (result)
{
fittingArgument = new InternalToBeResolvedPlaceholder(registeredType, parametersToResolve);
break;
}
constructorNotMatchingExceptions.AddRange(exceptions); if (result)
} fittingArgument = new InternalToBeResolvedPlaceholder(registeredType, parametersToResolve);
else
constructorNotMatchingExceptions.Add(new ConstructorNotMatchingException(constructor, exception));
} }
} }
catch (Exception exception) catch (Exception exception)

@ -116,8 +116,11 @@ namespace Test.LightweightIocContainer
NoMatchingConstructorFoundException noMatchingConstructorFoundException = Assert.Throws<NoMatchingConstructorFoundException>(() => _iocContainer.Resolve<IFoo>()); NoMatchingConstructorFoundException noMatchingConstructorFoundException = Assert.Throws<NoMatchingConstructorFoundException>(() => _iocContainer.Resolve<IFoo>());
ConstructorNotMatchingException fooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingConstructorFoundException?.InnerExceptions[0]; ConstructorNotMatchingException fooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingConstructorFoundException?.InnerExceptions[0];
ConstructorNotMatchingException barConstructorNotMatchingException = (ConstructorNotMatchingException) fooConstructorNotMatchingException?.InnerExceptions[0]; ConstructorNotMatchingException barConstructorNotMatchingException = (ConstructorNotMatchingException) fooConstructorNotMatchingException?.InnerExceptions[0];
NoMatchingConstructorFoundException noMatchingBarConstructorFoundException = (NoMatchingConstructorFoundException) barConstructorNotMatchingException?.InnerExceptions[0];
ConstructorNotMatchingException secondFooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingBarConstructorFoundException?.InnerExceptions[0];
ConstructorNotMatchingException secondBarConstructorNotMatchingException = (ConstructorNotMatchingException) secondFooConstructorNotMatchingException?.InnerExceptions[0];
CircularDependencyException exception = (CircularDependencyException) barConstructorNotMatchingException?.InnerExceptions[0]; CircularDependencyException exception = (CircularDependencyException) secondBarConstructorNotMatchingException?.InnerExceptions[0];
Assert.AreEqual(typeof(IFoo), exception?.ResolvingType); Assert.AreEqual(typeof(IFoo), exception?.ResolvingType);
Assert.AreEqual(2, exception.ResolveStack.Count); Assert.AreEqual(2, exception.ResolveStack.Count);

Loading…
Cancel
Save