Skip to content

Commit

Permalink
ParameterCompatibleWithTypeConstraint returns true instead of false w…
Browse files Browse the repository at this point in the history
…hen resolving open generic service autofac#794 issue fixed
  • Loading branch information
sebekz committed Sep 13, 2016
1 parent 9c605d3 commit 5dee89c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/Autofac/Util/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ private static bool ParameterEqualsConstraint(Type parameter, Type constraint)
try
{
var genericType = typeDefinition.MakeGenericType(genericArguments);
var constraintArguments = constraint.GetTypeInfo().GenericTypeArguments;

for (int i = 0; i < constraintArguments.Count(); i++)
{
var constraintArgument = constraintArguments[i].GetTypeInfo();
if (!constraintArgument.IsGenericParameter && !constraintArgument.IsAssignableFrom(genericArguments[i].GetTypeInfo())) return false;
}

return genericType == parameter;
}
catch (Exception)
Expand Down
64 changes: 64 additions & 0 deletions test/Autofac.Test/Features/OpenGenerics/ComplexGenericsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,69 @@ public void CanResolveByGenericInterface()
var validator = container.Resolve<CompanyA.IValidator<int>>();
Assert.IsType<CompanyA.CompositeValidator<int>>(validator);
}

public interface ISimpleInterface
{
}

public interface IOtherSimpleInterface
{
}

public interface ISingleGeneric<T>
{
}

public interface ISingleGenericWithOutModifier<out T>
{
}

public interface IDoubleGenericWithInModifier<in T1, T2>
{
}

public class CSimple : ISimpleInterface
{
}

public class COther : IOtherSimpleInterface
{
}

public class CNestedConstrainted<T1, T2> : IDoubleGenericWithInModifier<T1, T2>
where T2 : ISingleGenericWithOutModifier<ISimpleInterface>
{
}

public class COtherNestedConstrainted<T1, T2> : IDoubleGenericWithInModifier<T1, T2>
where T2 : ISingleGenericWithOutModifier<IOtherSimpleInterface>
{
}

[Fact]
public void CanResolveComponentUsingInterfaceWhenConstraintAndClassUseNestedInterfaces()
{
var builder = new ContainerBuilder();

builder.RegisterGeneric(typeof(CNestedConstrainted<,>))
.As(typeof(IDoubleGenericWithInModifier<,>));

builder.RegisterGeneric(typeof(COtherNestedConstrainted<,>))
.As(typeof(IDoubleGenericWithInModifier<,>));

var container = builder.Build();

// These simple concrete implementations lookup which were failing as per issue #794
Assert.True(container.IsRegistered<IDoubleGenericWithInModifier<int, ISingleGenericWithOutModifier<CSimple>>>());
Assert.True(container.IsRegistered<IDoubleGenericWithInModifier<int, ISingleGenericWithOutModifier<COther>>>());

// These a little bit more complex concrete implementations lookup were failing as well as per issue #794
Assert.True(container.IsRegistered<IDoubleGenericWithInModifier<ISingleGeneric<ISingleGenericWithOutModifier<CSimple>>, ISingleGenericWithOutModifier<CSimple>>>());
Assert.True(container.IsRegistered<IDoubleGenericWithInModifier<ISingleGeneric<ISingleGenericWithOutModifier<COther>>, ISingleGenericWithOutModifier<COther>>>());

// These should resolve, but per issue #794 exceptions were thrown
container.Resolve<IDoubleGenericWithInModifier<ISingleGeneric<ISingleGenericWithOutModifier<CSimple>>, ISingleGenericWithOutModifier<CSimple>>>();
container.Resolve<IDoubleGenericWithInModifier<ISingleGeneric<ISingleGenericWithOutModifier<CSimple>>, ISingleGenericWithOutModifier<COther>>>();
}
}
}

0 comments on commit 5dee89c

Please # to comment.