[英]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.