Skip to content

Commit

Permalink
Merge pull request #588 from seesharper/bugfix-generic-type-mapper
Browse files Browse the repository at this point in the history
Bugfix in GenericTypeMapper
  • Loading branch information
seesharper committed May 8, 2023
2 parents 476a36a + 82f60e6 commit 9ed86cc
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 7 deletions.
57 changes: 51 additions & 6 deletions src/LightInject.Tests/OpenGenericTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Reflection;
using LightInject.SampleLibrary;
using Xunit;

Expand All @@ -10,7 +11,7 @@ public class OpenGenericTests : TestBase
public void GetInstance_PartiallyClosedGeneric_ReturnsInstance()
{
var container = CreateContainer();
container.Register(typeof (IFoo<,>), typeof (HalfClosedFoo<>));
container.Register(typeof(IFoo<,>), typeof(HalfClosedFoo<>));

var instance = container.GetInstance<IFoo<string, int>>();

Expand Down Expand Up @@ -43,9 +44,9 @@ public void GetInstance_PartiallyClosedGenericWithDoubleNestedArgument_ReturnsIn
public void GetInstance_PartialClosedAbstractClass_ReturnsInstance()
{
var container = CreateContainer();
container.Register(typeof (Foo<,>), typeof (HalfClosedFooInhertingFromBaseClass<>));
container.Register(typeof(Foo<,>), typeof(HalfClosedFooInhertingFromBaseClass<>));

var instance = container.GetInstance<Foo<string,int>>();
var instance = container.GetInstance<Foo<string, int>>();

Assert.IsType<HalfClosedFooInhertingFromBaseClass<int>>(instance);
}
Expand All @@ -54,7 +55,7 @@ public void GetInstance_PartialClosedAbstractClass_ReturnsInstance()
public void GetInstance_ConcreteClass_ReturnsInstance()
{
var container = CreateContainer();
container.Register(typeof (Foo<>));
container.Register(typeof(Foo<>));

var instance = container.GetInstance<Foo<int>>();

Expand Down Expand Up @@ -84,9 +85,9 @@ public void GetInstance_NamedServiceWithInvalidConstraint_ThrowsException()
[Fact]
public void GetInstance_NoMatchingOpenGeneric_ThrowsException()
{
var container = CreateContainer();
var container = CreateContainer();

Assert.Throws<InvalidOperationException>(() => container.GetInstance<IFoo<int>>());
Assert.Throws<InvalidOperationException>(() => container.GetInstance<IFoo<int>>());

}

Expand All @@ -101,5 +102,49 @@ public void GetInstance_NamedOpenGenerics_IgnoresCaseOnServiceNames()

Assert.IsType<Foo<int>>(instance);
}

[Fact]
public void ShouldMapNestGenericArguments()
{
var container = CreateContainer();

container.Register(typeof(IHandler<>), typeof(Handler<>), "Handler");
container.Register(typeof(IHandler<>), typeof(AnotherHandler<>), "AnotherHandler");

var handlerInstance = container.GetInstance<IHandler<Message<string>>>();
Assert.IsType<Handler<string>>(handlerInstance);
var anotherHandlerInstance = container.GetInstance<IHandler<AnotherMessage<string>>>();
Assert.IsType<AnotherHandler<string>>(anotherHandlerInstance);
}
}

public interface IHandler<TCommand>
{
}

public class Message<TMessage>
{

}

public class AnotherMessage<TAnotherMessage>
{

}

public class Handler<TCommand> : IHandler<Message<TCommand>>
{
public Handler()
{

}
}

public class AnotherHandler<TCommand> : IHandler<AnotherMessage<TCommand>>
{
public AnotherHandler()
{

}
}
}
10 changes: 9 additions & 1 deletion src/LightInject/LightInject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4484,9 +4484,14 @@ private Action<IEmitter> CreateEmitMethodBasedOnClosedGenericServiceRequest(Type
foreach (var openGenericServiceRegistration in openGenericServiceRegistrations.Values)
{
var closedGenericImplementingTypeCandidate = GenericArgumentMapper.TryMakeGenericType(closedGenericServiceType, openGenericServiceRegistration.ImplementingType);

if (closedGenericImplementingTypeCandidate != null)
{
candidates.Add(openGenericServiceRegistration.ServiceName, new ClosedGenericCandidate(closedGenericImplementingTypeCandidate, openGenericServiceRegistration.Lifetime));
// Ensure that we only add candidates that are assignable to the requested service type.
if (closedGenericServiceType.IsAssignableFrom(closedGenericImplementingTypeCandidate))
{
candidates.Add(openGenericServiceRegistration.ServiceName, new ClosedGenericCandidate(closedGenericImplementingTypeCandidate, openGenericServiceRegistration.Lifetime));
}
}
}

Expand Down Expand Up @@ -7171,6 +7176,9 @@ public class GenericArgumentMapper : IGenericArgumentMapper
/// <returns>A <see cref="GenericMappingResult"/>.</returns>
public GenericMappingResult Map(Type genericServiceType, Type openGenericImplementingType)
{
// string[] genericParameterNames = GetGenericArgumentsOrParameters(genericServiceType).Select(t => t.Name).ToArray();


string[] genericParameterNames =
openGenericImplementingType.GetTypeInfo().GenericTypeParameters.Select(t => t.Name).ToArray();

Expand Down

0 comments on commit 9ed86cc

Please sign in to comment.