#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>
[CanBeNull]
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;
@ -496,31 +523,14 @@ namespace LightweightIocContainer
(bool result, List<object> parameters, List<ConstructorNotMatchingException> exceptions) = TryGetConstructorResolveStack(constructor, 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();
}
return (true, parameters, null);
noMatchingConstructorFoundException ??= new NoMatchingConstructorFoundException(type);
exceptions.ForEach(e =>
exceptions?.ForEach(e =>
noMatchingConstructorFoundException.AddInnerException(new ConstructorNotMatchingException(constructor, e)));
}
if (noMatchingConstructorFoundException != null)
throw noMatchingConstructorFoundException;
return null;
return (false, null, noMatchingConstructorFoundException);
}
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);
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);
@ -568,19 +578,13 @@ namespace LightweightIocContainer
if (registration is IWithParametersInternal { Parameters: { } } registrationWithParameters)
argumentsForRegistration = UpdateArgumentsWithRegistrationParameters(registrationWithParameters, null);
foreach (ConstructorInfo registeredTypeConstructor in TryGetSortedConstructors(registeredType))
{
(bool result, List<object> parametersToResolve, List<ConstructorNotMatchingException> exceptions) =
TryGetConstructorResolveStack(registeredTypeConstructor, argumentsForRegistration, internalResolveStack);
if (result)
{
fittingArgument = new InternalToBeResolvedPlaceholder(registeredType, parametersToResolve);
break;
}
(bool result, List<object> parametersToResolve, NoMatchingConstructorFoundException exception) =
TryGetTypeResolveStack(registeredType, argumentsForRegistration, internalResolveStack);
constructorNotMatchingExceptions.AddRange(exceptions);
}
if (result)
fittingArgument = new InternalToBeResolvedPlaceholder(registeredType, parametersToResolve);
else
constructorNotMatchingExceptions.Add(new ConstructorNotMatchingException(constructor, exception));
}
}
catch (Exception exception)

@ -116,8 +116,11 @@ namespace Test.LightweightIocContainer
NoMatchingConstructorFoundException noMatchingConstructorFoundException = Assert.Throws<NoMatchingConstructorFoundException>(() => _iocContainer.Resolve<IFoo>());
ConstructorNotMatchingException fooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingConstructorFoundException?.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(2, exception.ResolveStack.Count);

Loading…
Cancel
Save