diff --git a/LightweightIocContainer/IocContainer.cs b/LightweightIocContainer/IocContainer.cs index 395f217..5660186 100644 --- a/LightweightIocContainer/IocContainer.cs +++ b/LightweightIocContainer/IocContainer.cs @@ -487,8 +487,35 @@ namespace LightweightIocContainer [CanBeNull] private object[] ResolveTypeCreationArguments(Type type, object[] arguments, List resolveStack) { - NoMatchingConstructorFoundException noMatchingConstructorFoundException = null; + (bool result, List parameters, NoMatchingConstructorFoundException exception) = TryGetTypeResolveStack(type, arguments, resolveStack); + + if (result) + { + if (parameters == null) + return null; + + List 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 parameters, NoMatchingConstructorFoundException exception) TryGetTypeResolveStack(Type type, object[] arguments, List resolveStack) + { + NoMatchingConstructorFoundException noMatchingConstructorFoundException = null; + //find best ctor List sortedConstructors = TryGetSortedConstructors(type); foreach (ConstructorInfo constructor in sortedConstructors) @@ -496,31 +523,14 @@ namespace LightweightIocContainer (bool result, List parameters, List exceptions) = TryGetConstructorResolveStack(constructor, arguments, resolveStack); if (result) - { - if (parameters == null) - return null; - - List 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 parameters, List constructorNotMatchingExceptions) TryGetConstructorResolveStack(ConstructorInfo constructor, object[] arguments, List resolveStack) @@ -555,7 +565,7 @@ namespace LightweightIocContainer IRegistration registration = FindRegistration(parameter.ParameterType) ?? throw new TypeNotRegisteredException(parameter.ParameterType); List 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 parametersToResolve, List exceptions) = - TryGetConstructorResolveStack(registeredTypeConstructor, argumentsForRegistration, internalResolveStack); - - if (result) - { - fittingArgument = new InternalToBeResolvedPlaceholder(registeredType, parametersToResolve); - break; - } + (bool result, List 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) diff --git a/Test.LightweightIocContainer/IocContainerRecursionTest.cs b/Test.LightweightIocContainer/IocContainerRecursionTest.cs index eddf3d5..7f480e0 100644 --- a/Test.LightweightIocContainer/IocContainerRecursionTest.cs +++ b/Test.LightweightIocContainer/IocContainerRecursionTest.cs @@ -116,8 +116,11 @@ namespace Test.LightweightIocContainer NoMatchingConstructorFoundException noMatchingConstructorFoundException = Assert.Throws(() => _iocContainer.Resolve()); 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);