Autofac正在解析IEnumerable <icontravariantinterface <concreteobject>&gt; as IEnumerable <icontravariantinterface <object>&gt; [0]

时间:2017-09-15 19:20:45

标签: c# autofac

public interface IDomainValidator<in TDomain>{}

public interface IDomainValidation<TDomain> {
    void Validate(TDomain domain);
}

public class DomainValidation<TDomain> : IDomainValidation<TDomain>
{
    public DomainValidation(IEnumerable<IDomainValidator<TDomain>> validators)
    {
      ....
    }
}

我遇到的问题是逆变接口被解析为IEnumerable<IDomainValidator<object>>的空数组。我的单元/集成测试工作正常,所以我必须假设还有其他东西被注册导致问题。

我是否有办法确定如何将这些封闭类型作为对象返回,而不是实现这些封闭类型的已注册类型?

更新1

我意识到我是从一个通用类型调用它,它实际上是可能存在问题的那个。 DomainValidation<TDomain>也遇到了对象,它解释了域验证器的列表。 DomainValidation正在注册:

builder.RegisterGeneric(typeof(DomainValidation<>)).As(typeof(IDomainValidation<>));

它被注入一个类,如:

public class Implementation
{
    public Implementation(IDomainValidation<SomeClass> validation) {...}

}

这个类在技术上是错误的。它也显示为对象

更新2

IComponentRegistration显示正确的IDomainValidation<SomeClass>类型,它确实有ContravariantAdapter,服务显示正确的类型。目标显示为+ Target {Activator = DomainValidation 1(ReflectionActivator),服务= [Flightdocs.Infrastructure.Validation.Domain.IDomainValidation 1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope} Autofac.Core.IComponentRegistration {Autofac.Core.Registration.ComponentRegistration}我猜是问题出在哪里。现在我不知道为什么会这样。我假设某些东西正在注册为IDomainValidation<object>

2 个答案:

答案 0 :(得分:1)

由于IContravariantInterface<T>是逆变的(例如,它包含in个参数),这意味着IContravariantInterface<ConcreteObject>可以投放到IContravariantInterface<ConcreteSubObject>但不能投放到IContravariantInterface<object>。将其投放到IContravariantInterface<object>将允许消费者传递与ConcreteObject完全不同的内容(例如System.String),这显然会破坏实施IContravariantInterface<ConcreteObject>的类。

因此从这个意义上来说,很明显,已注册的IContravariantInterface<ConcreteObject>列表最终会成为IContravariantInterface<object>的零实例。为了能够执行此操作,您必须将IContravariantInterface<T>更改为covarant(即使用out关键字),但这会禁用T作为输入参数。

答案 1 :(得分:0)

我设法弄明白我的问题是什么。我有另一个我使用的模块(MediatR)建议使用if nargin==5 % so length(varargin)==2 它显然不适用于Contravariant通用接口。一旦我删除它,那么这些接口就填充了正确的对象类型。