繁体   English   中英

Autofac正在解决IEnumerable <IContravariantInterface<ConcreteObject> &gt;作为IEnumerable <IContravariantInterface<object> &gt; [0]

[英]Autofac is resolving IEnumerable<IContravariantInterface<ConcreteObject>> as IEnumerable<IContravariantInterface<object>>[0]

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>>接口解析为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>

由于IContravariantInterface<T>IContravariantInterface<T> (例如,它包含in参数中),这意味着IContravariantInterface<ConcreteObject>可以IContravariantInterface<ConcreteSubObject>转换为IContravariantInterface<ConcreteSubObject>而不能IContravariantInterface<object>IContravariantInterface<object> 将其IContravariantInterface<object>转换为IContravariantInterface<object>将允许使用者传递与ConcreteObject完全不同的内容(例如System.String ),这显然会破坏实现IContravariantInterface<ConcreteObject>的类。

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

我设法弄清楚我的问题是什么。 我有另一个模块(MediatR),该模块建议使用builder.RegisterSource(new ContravariantRegistrationSource()); 对于Contravariant通用接口,它显然不能很好地工作。 删除它后,这些接口将填充正确的对象类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM