微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

依赖注入通用抽象类的IEnumerable

如何解决依赖注入通用抽象类的IEnumerable

我有多个类扩展了通用抽象基类:

public class BaseDetails {}

public class ADetails : BaseDetails {}
public class BDetails : BaseDetails {}

public abstract class Base<T> {}
public class A : Base<ADetails> {}
public class B : Base<BDetails> {}

这一切正常,我正在努力的是依赖注入,用于注册通用抽象基类的许多实现,所以我想要的是:

IEnumerable<Base<BaseDetails>> _baseClasses;

我试图像这样去DI,但是没有运气:

builder.RegisterMany(new[] { Assembly.Load(nameof(Program)) },type => type.IsAssignableto(typeof(Base<>)));

我觉得我在DI方面缺少一些东西,非常感谢您的帮助!

解决方法

欢迎来到covariance and contravariance的世界。尽管IEnumerable<T>是协变的,但您的Base<T>类却不是,因为类不能应用任何变化。只有接口和委托可以。这意味着以下代码无法编译:

Base<BaseDetails> b = new A();

上面的代码是一个重要的练习,因为涉及泛型时,DI容器很容易使您误以为问题出在DI容器中。始终尝试在不使用DI容器的情况下通过手动连接对象图来重建问题。例如:

IEnumerable<Base<BaseDetails>> _baseClasses = new Base<BaseDetails>[]
{
    new A(),// <- compile error here
    new B(),// <- compile error here
};

同样,此代码不会在C#中编译:

CS0029无法将类型“ A”隐式转换为“基本”

要执行此操作,必须将Base<T>更改为接口,并使它的T通用参数为协变量:

public interface Base<out T> { }
,

类似这样的东西:

builder.RegisterMany(new[] { Assembly.Load(nameof(Program)) },type => type.IsGeneric && type.GetGenericTypeDefinition() == typeof(Base<>)));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。