簡體   English   中英

"Autofac 逆變和解析開放的泛型類型"

[英]Autofac contravariance and resolving open generic types

從 autofac 解析泛型類型(具有逆變 T)的所有實現時,我想獲得所有可能的逆變匹配。 這僅在注冊ContravariantRegistrationSource<\/em>時有效。 但是后來我得到了太多用於開放通用實現的實例,因為它遍歷繼承樹為每個子類提供了一個實例。

這聽起來可能有點抽象,所以這里有 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);
        }
    }    
}

該問題與ContravariantRegistrationSource<\/code>和RegisterGeneric<\/code>的工作方式有關

當您解決GenericImplementation<TClass><\/code>時, ContravariantRegistrationSource<\/code>將嘗試解決

GenericImplementation<TClass>
GenericImplementation<Object>
GenericImplementation<TInterface>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM