From 36e266f560d51a4bd2d7c00913d8ece91b41f255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sitko?= Date: Wed, 21 Dec 2016 22:35:52 +0100 Subject: [PATCH] resolve generics constrained with generic parameters --- src/Autofac/Util/TypeExtensions.cs | 7 +++++++ .../OpenGenerics/ComplexGenericsTests.cs | 19 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Autofac/Util/TypeExtensions.cs b/src/Autofac/Util/TypeExtensions.cs index 4c4195903..6a1b4b57b 100644 --- a/src/Autofac/Util/TypeExtensions.cs +++ b/src/Autofac/Util/TypeExtensions.cs @@ -74,6 +74,7 @@ public static bool IsCompatibleWithGenericParameterConstraints(this Type generic var parameterTypeInfo = parameter.GetTypeInfo(); if (argumentDefinitionTypeInfo.GetGenericParameterConstraints() + .Select(constraint => SubstituteGenericParameterConstraint(parameters, constraint)) .Any(constraint => !ParameterCompatibleWithTypeConstraint(parameter, constraint))) { return false; @@ -160,6 +161,12 @@ private static IEnumerable FindAssignableTypesThatClose(Type candidateType .Where(t => t.IsClosedTypeOf(openGenericServiceType)); } + private static Type SubstituteGenericParameterConstraint(Type[] parameters, Type constraint) + { + if (!constraint.IsGenericParameter) return constraint; + return parameters[constraint.GenericParameterPosition]; + } + private static bool ParameterCompatibleWithTypeConstraint(Type parameter, Type constraint) { return constraint.GetTypeInfo().IsAssignableFrom(parameter.GetTypeInfo()) || diff --git a/test/Autofac.Test/Features/OpenGenerics/ComplexGenericsTests.cs b/test/Autofac.Test/Features/OpenGenerics/ComplexGenericsTests.cs index 0cafbf18b..7509a6bc7 100644 --- a/test/Autofac.Test/Features/OpenGenerics/ComplexGenericsTests.cs +++ b/test/Autofac.Test/Features/OpenGenerics/ComplexGenericsTests.cs @@ -220,10 +220,27 @@ public void CanResolveComponentWhenConstraintsAreNested() builder.RegisterGeneric(typeof(MultiConstrained<,>)); var container = builder.Build(); - + Assert.True(container.IsRegistered>>()); } + public class ConstrainedWithGenericParameter + where T1 : T2 + { + } + + [Fact] + public void CanResolveComponentWhenGenericParameterIsConstrainedWithOtherGenericParameter() + { + var builder = new ContainerBuilder(); + + builder.RegisterGeneric(typeof(ConstrainedWithGenericParameter<,>)); + + var container = builder.Build(); + + Assert.True(container.IsRegistered>()); + } + [Fact(Skip = "Issue #688")] public void GenericArgumentArityDifference() {