#51: extract tryGetTypeResolveStack() method

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

@ -487,13 +487,7 @@ namespace LightweightIocContainer
[CanBeNull] [CanBeNull]
private object[] ResolveTypeCreationArguments(Type type, object[] arguments, List<Type> resolveStack) private object[] ResolveTypeCreationArguments(Type type, object[] arguments, List<Type> resolveStack)
{ {
NoMatchingConstructorFoundException noMatchingConstructorFoundException = null; (bool result, List<object> parameters, NoMatchingConstructorFoundException exception) = TryGetTypeResolveStack(type, arguments, resolveStack);
//find best ctor
List<ConstructorInfo> sortedConstructors = TryGetSortedConstructors(type);
foreach (ConstructorInfo constructor in sortedConstructors)
{
(bool result, List<object> parameters, List<ConstructorNotMatchingException> exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack);
if (result) if (result)
{ {
@ -512,15 +506,31 @@ namespace LightweightIocContainer
return constructorParameters.ToArray(); 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;
//find best ctor
List<ConstructorInfo> sortedConstructors = TryGetSortedConstructors(type);
foreach (ConstructorInfo constructor in sortedConstructors)
{
(bool result, List<object> parameters, List<ConstructorNotMatchingException> exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack);
if (result)
return (true, parameters, null);
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) if (result)
{
fittingArgument = new InternalToBeResolvedPlaceholder(registeredType, parametersToResolve); fittingArgument = new InternalToBeResolvedPlaceholder(registeredType, parametersToResolve);
break; else
} constructorNotMatchingExceptions.Add(new ConstructorNotMatchingException(constructor, exception));
constructorNotMatchingExceptions.AddRange(exceptions);
}
} }
} }
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