Autofac逆变和解决开放泛型类型

时间:2017-09-28 08:52:17

标签: c# generics autofac contravariance

当从autofac解析泛型类型(具有逆变T)的所有实现时,我希望获得所有可能的逆变匹配。这仅在注册 ContravariantRegistrationSource 时有效。但是后来我为开放式泛型实现获得了太多实例,因为它遍历继承树为每个子类提供了一个实例。

这可能听起来有点抽象,所以这里有2个单元测试来证明这个问题。他们都失败了,但我想让至少其中一人工作:

using Autofac;
using FluentAssertions;
using System.Collections.Generic;
using Xunit;
using Autofac.Features.Variance;

namespace Aiv.Vbr.QueryService.WebApi.Test.AdresMatchTests
{
    public class TestAutofacGenerics
    {
        public interface IGenericInterface<in T> { }
        public class GenericImplementation<T> : IGenericInterface<T> { }
        public class SpecificImplementation : IGenericInterface<TClass> { }
        public class TInterfaceImplementation : IGenericInterface<TInterface> { }
        public interface TInterface { }
        public class TClass : TInterface { }

        [Fact]
        public void AutofacShouldAlsoResolveContravariantImplementations()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<SpecificImplementation>().As<IGenericInterface<TClass>>();
            builder.RegisterType<TInterfaceImplementation>().As<IGenericInterface<TInterface>>();
            builder.RegisterGeneric(typeof(GenericImplementation<>)).As(typeof(IGenericInterface<>));

            var instances = builder.Build().Resolve<IEnumerable<IGenericInterface<TClass>>>();

            //This fails: only 2 types get resolved: GenericImplementation<TClass> and SpecificImplementation
            //but also expected TInterfaceImplementation
            instances.Should().HaveCount(3);
        }

        [Fact]
        public void AutofacShouldOnlyResolveOpenGenericsForSpecifiedClass()
        {
            var builder = new ContainerBuilder();
            builder.RegisterSource(new ContravariantRegistrationSource());
            builder.RegisterType<SpecificImplementation>().As<IGenericInterface<TClass>>();
            builder.RegisterType<TInterfaceImplementation>().As<IGenericInterface<TInterface>>();
            builder.RegisterGeneric(typeof(GenericImplementation<>)).As(typeof(IGenericInterface<>));

            var instances = builder.Build().Resolve<IEnumerable<IGenericInterface<TClass>>>();

            //This fails: 5 types get resolved: GenericImplementation<TClass>, GenericImplementation<Object>, 
            // GenericImplementation<TInterface>, SpecificImplementation and TInteraceImplementation
            //but did not want GenericImplementation<Object> and GenericImplementation<TInterface>
            instances.Should().HaveCount(3);
        }
    }    
}

问题描述为here,建议的可能解决方案是使用作用域的自定义 ContravariantRegistrationSource ,但我无法看到它如何解决我的问题。 我该怎么办?

0 个答案:

没有答案
相关问题