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