#58: fix double wrapped constructorNotMatchingExceptions

pull/59/head
Simon G 3 years ago
parent 66f3d78d1e
commit e5b984a058
  1. 5
      LightweightIocContainer/IocContainer.cs
  2. 17
      Test.LightweightIocContainer/FluentFactoryRegistrationTest.cs
  3. 8
      Test.LightweightIocContainer/IocContainerRecursionTest.cs
  4. 61
      Test.LightweightIocContainer/IocValidatorTest.cs

@ -140,6 +140,7 @@ namespace LightweightIocContainer
/// <typeparam name="T">The registered <see cref="Type"/></typeparam> /// <typeparam name="T">The registered <see cref="Type"/></typeparam>
/// <returns>An instance of the given registered <see cref="Type"/>, an <see cref="InternalToBeResolvedPlaceholder"/> if parameters need to be resolved or an <see cref="InternalFactoryMethodPlaceholder{T}"/> if a factory method is used to create an instance</returns> /// <returns>An instance of the given registered <see cref="Type"/>, an <see cref="InternalToBeResolvedPlaceholder"/> if parameters need to be resolved or an <see cref="InternalFactoryMethodPlaceholder{T}"/> if a factory method is used to create an instance</returns>
/// <exception cref="TypeNotRegisteredException">The given <see cref="Type"/> is not registered</exception> /// <exception cref="TypeNotRegisteredException">The given <see cref="Type"/> is not registered</exception>
/// <exception cref="DirectResolveWithRegisteredFactoryNotAllowed">A direct resolve with a registered factory is not allowed</exception>
/// <exception cref="InvalidRegistrationException">An interface was registered without an implementation or factory method</exception> /// <exception cref="InvalidRegistrationException">An interface was registered without an implementation or factory method</exception>
/// <exception cref="MultitonResolveException">Tried resolving a multiton without scope argument</exception> /// <exception cref="MultitonResolveException">Tried resolving a multiton without scope argument</exception>
/// <exception cref="NoMatchingConstructorFoundException">No matching constructor for the given <see cref="Type"/> found</exception> /// <exception cref="NoMatchingConstructorFoundException">No matching constructor for the given <see cref="Type"/> found</exception>
@ -201,6 +202,7 @@ namespace LightweightIocContainer
/// <param name="isFactoryResolve"></param> /// <param name="isFactoryResolve"></param>
/// <returns>An instance of the given registered <see cref="Type"/>, an <see cref="InternalToBeResolvedPlaceholder"/> if parameters need to be resolved or an <see cref="InternalFactoryMethodPlaceholder{T}"/> if a factory method is used to create an instance</returns> /// <returns>An instance of the given registered <see cref="Type"/>, an <see cref="InternalToBeResolvedPlaceholder"/> if parameters need to be resolved or an <see cref="InternalFactoryMethodPlaceholder{T}"/> if a factory method is used to create an instance</returns>
/// <exception cref="TypeNotRegisteredException">The given <see cref="Type"/> is not registered</exception> /// <exception cref="TypeNotRegisteredException">The given <see cref="Type"/> is not registered</exception>
/// <exception cref="DirectResolveWithRegisteredFactoryNotAllowed">A direct resolve with a registered factory is not allowed</exception>
/// <exception cref="InvalidRegistrationException">An interface was registered without an implementation or factory method</exception> /// <exception cref="InvalidRegistrationException">An interface was registered without an implementation or factory method</exception>
/// <exception cref="MultitonResolveException">Tried resolving a multiton without scope argument</exception> /// <exception cref="MultitonResolveException">Tried resolving a multiton without scope argument</exception>
/// <exception cref="NoMatchingConstructorFoundException">No matching constructor for the given <see cref="Type"/> found</exception> /// <exception cref="NoMatchingConstructorFoundException">No matching constructor for the given <see cref="Type"/> found</exception>
@ -464,8 +466,7 @@ namespace LightweightIocContainer
return (true, parameters, null); return (true, parameters, null);
noMatchingConstructorFoundException ??= new NoMatchingConstructorFoundException(type); noMatchingConstructorFoundException ??= new NoMatchingConstructorFoundException(type);
exceptions?.ForEach(e => exceptions?.ForEach(e => noMatchingConstructorFoundException.AddInnerException(e));
noMatchingConstructorFoundException.AddInnerException(new ConstructorNotMatchingException(constructor, e)));
} }
return (false, null, noMatchingConstructorFoundException); return (false, null, noMatchingConstructorFoundException);

@ -113,9 +113,18 @@ namespace Test.LightweightIocContainer
ITestFactory factory = _iocContainer.Resolve<ITestFactory>(); ITestFactory factory = _iocContainer.Resolve<ITestFactory>();
ITest test = factory.Create(); ITest test = factory.Create();
ITest test2 = factory.CreateTest();
Assert.IsInstanceOf<ITestFactory>(factory); Assert.IsInstanceOf<ITestFactory>(factory);
Assert.IsInstanceOf<ITest>(test); Assert.IsInstanceOf<ITest>(test);
Assert.IsInstanceOf<ITest>(test2);
}
[Test]
public void TestFluentFactoryRegistrationResolveWithoutFactoryFails()
{
_iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactory>());
Assert.Throws<DirectResolveWithRegisteredFactoryNotAllowed>(()=>_iocContainer.Resolve<ITest>());
} }
[Test] [Test]
@ -130,6 +139,14 @@ namespace Test.LightweightIocContainer
Assert.IsInstanceOf<ITest>(test); Assert.IsInstanceOf<ITest>(test);
} }
[Test]
public void TestFluentFactoryRegistration_WithoutFactoryFails()
{
_iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactory, TestFactory>());
Assert.Throws<DirectResolveWithRegisteredFactoryNotAllowed>(()=>_iocContainer.Resolve<ITest>());
}
[Test] [Test]
public void TestRegisterFactoryWithoutCreate() => Assert.Throws<InvalidFactoryRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactoryNoCreate>())); public void TestRegisterFactoryWithoutCreate() => Assert.Throws<InvalidFactoryRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, Test>().WithFactory<ITestFactoryNoCreate>()));

@ -115,12 +115,10 @@ 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]; NoMatchingConstructorFoundException noMatchingBarConstructorFoundException = (NoMatchingConstructorFoundException) fooConstructorNotMatchingException?.InnerExceptions[0];
NoMatchingConstructorFoundException noMatchingBarConstructorFoundException = (NoMatchingConstructorFoundException) barConstructorNotMatchingException?.InnerExceptions[0]; ConstructorNotMatchingException barConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingBarConstructorFoundException?.InnerExceptions[0];
ConstructorNotMatchingException secondFooConstructorNotMatchingException = (ConstructorNotMatchingException) noMatchingBarConstructorFoundException?.InnerExceptions[0];
ConstructorNotMatchingException secondBarConstructorNotMatchingException = (ConstructorNotMatchingException) secondFooConstructorNotMatchingException?.InnerExceptions[0];
CircularDependencyException exception = (CircularDependencyException) secondBarConstructorNotMatchingException?.InnerExceptions[0]; CircularDependencyException exception = (CircularDependencyException) barConstructorNotMatchingException?.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);

@ -22,6 +22,11 @@ namespace Test.LightweightIocContainer
} }
public interface ITest2
{
}
[UsedImplicitly] [UsedImplicitly]
public interface IParameter public interface IParameter
{ {
@ -33,12 +38,30 @@ namespace Test.LightweightIocContainer
public Test(IParameter parameter) => parameter.Method(); public Test(IParameter parameter) => parameter.Method();
} }
[UsedImplicitly] [UsedImplicitly]
public interface ITestFactory public interface ITestFactory
{ {
ITest Create(IParameter parameter); ITest Create(IParameter parameter);
} }
[UsedImplicitly]
public interface ITest2Factory
{
ITest2 InvalidCreate();
ITest2 Create(ITest test);
}
private class Test2 : ITest2
{
public Test2(ITest parameter)
{
}
}
[UsedImplicitly] [UsedImplicitly]
public interface IInvalidFactory public interface IInvalidFactory
{ {
@ -60,6 +83,15 @@ namespace Test.LightweightIocContainer
public void Install(IRegistrationCollector registration) => registration.Add<ITest, Test>().WithFactory<IInvalidFactory>(); public void Install(IRegistrationCollector registration) => registration.Add<ITest, Test>().WithFactory<IInvalidFactory>();
} }
private class InvalidTestClassInstaller : IIocInstaller
{
public void Install(IRegistrationCollector registration)
{
registration.Add<ITest, Test>().WithFactory<ITestFactory>();
registration.Add<ITest2, Test2>().WithFactory<ITest2Factory>();
}
}
[Test] [Test]
public void TestValidateWithoutFactory() public void TestValidateWithoutFactory()
{ {
@ -102,6 +134,35 @@ namespace Test.LightweightIocContainer
parameterMock.Verify(p => p.Method(), Times.Never); parameterMock.Verify(p => p.Method(), Times.Never);
} }
[Test]
public void TestValidateWithInvalidParameterWithFactory()
{
IocContainer iocContainer = new();
iocContainer.Install(new InvalidTestClassInstaller());
IocValidator validator = new(iocContainer);
Mock<IParameter> parameterMock = new();
validator.AddParameter<ITest, IParameter>(parameterMock.Object);
AggregateException aggregateException = Assert.Throws<AggregateException>(() => validator.Validate());
if (aggregateException?.InnerExceptions[0] is not NoMatchingConstructorFoundException noMatchingConstructorFoundException)
{
Assert.Fail();
return;
}
if (noMatchingConstructorFoundException.InnerExceptions[0] is not ConstructorNotMatchingException iTest2CtorNotMatchingException)
{
Assert.Fail();
return;
}
Assert.IsInstanceOf<DirectResolveWithRegisteredFactoryNotAllowed>(iTest2CtorNotMatchingException.InnerExceptions[0]);
}
[Test] [Test]
public void TestValidateInvalidFactory() public void TestValidateInvalidFactory()
{ {

Loading…
Cancel
Save