使用Autofac注册基类的实现,以通过IEnumerable传入

Ale*_*lex 9 c# dependency-injection inversion-of-control autofac

我有一个基类,还有一系列继承自此类的其他类:(
请原谅过度使用的动物类比)

公共抽象类Animal {}

公共类狗:动物{}

公共课Cat:Animal {}

然后我有一个依赖于一个类的类 IEnumerable<Animal>

public class AnimalFeeder
{
    private readonly IEnumerable<Animal> _animals;

    public AnimalFeeder(IEnumerable<Animal> animals )
    {
        _animals = animals;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我手动做这样的事情:

var animals =
    typeof(Animal).Assembly.GetTypes()
        .Where(x => x.IsSubclassOf(typeof(Animal)))
        .ToList();
Run Code Online (Sandbox Code Playgroud)

然后我可以看到它返回Dog并且Cat

但是,当我尝试连接我的Autofac时:

builder.RegisterAssemblyTypes(typeof(Animal).Assembly)
    .Where(t => t.IsSubclassOf(typeof(Animal)));

builder.RegisterType<AnimalFeeder>();
Run Code Online (Sandbox Code Playgroud)

AnimalFeeder被实例化,没有Animal在传递给构造函数.

我错过了什么吗?

nem*_*esv 19

As<Animal>()在注册时错过了电话.

如果没有它,Autofac会使用默认AsSelf()设置注册您的类型,因此IEnumerable<Animal>只有在您使用像Dog和Cat这样的子类型时,如果您要求基类型,则不会获得您的类.

所以将注册更改为:

builder.RegisterAssemblyTypes(typeof(Animal).Assembly)
     .Where(t => t.IsSubclassOf(typeof(Animal)))
     .As<Animal>();
Run Code Online (Sandbox Code Playgroud)

  • 当命名注册使用类型 ** 和 ** 名称注册时,也可以使用 IEnumarable&lt;T&gt; 进行解析。所以 `builder.RegisterType&lt;Dog&gt;().As&lt;Animal&gt;().Named&lt;Animal&gt;("Dog"); builder.RegisterType&lt;Cat&gt;().As&lt;Animal&gt;().Named&lt;Animal&gt;("Cat");` 在这种情况下, `IEnumerable&lt;Animal&gt;` 将返回两者,但您也可以使用以下方法解析单个: `container.ResolveNamed&lt;Animal&gt;("Dog");`。您甚至可以将其与程序集扫描结合起来:`builder.RegisterAssemblyTypes(...).As&lt;Animal&gt;();`,然后另外注册您的命名对象:`builder.RegisterType&lt;Dog&gt;().Named&lt;Animal&gt; (“狗”);` (2认同)