Autofac:解决类型的所有实例


68

鉴于以下注册

builder.Register<A>().As<I>();
builder.Register<B>().As<I>();
builder.Register<C>().As<I>();

var container = builder.Build();

我正在寻求将类型I的所有实例解析为IEnumerable(数组或集合都没有关系)。

在温莎,我会写以下内容。

foreach(I i in container.ResolveAll<I>())
{
 ...
}

我正在从温莎迁移到Autofac 1.4.4.561,但看不到等效的语法。


您想分享为什么从温莎(Windsor)迁移到Autofac的任何原因?
Peter Lillevold 09年

我真正喜欢Autofac的事情是能够通过lamda表达式来表达动态组件的构造。通过使用表达式而不是自动装配,可以减少误解容器解析类型时在做什么的空间(注意:如果您愿意,autofac支持自动装配)。最终,当IOC作为一个概念实际上非常简单时,Windsor API变得如此巨大,以至于它迎合了每种复杂性的可能性。并不是说我永远不会再使用温莎,只是尝试其他选择。
crowleym

3
我曾考虑过从温莎迁至Autofac。温莎的API令人困惑。
艾米

Answers:


93

对于当前的Autofac版本:( 2.0+,因此您今天应该使用的任何东西)

您注册多个ILoggers(例如):

var builder = new ContainerBuilder();

builder.Register<ConsoleLogger>()
  .As<ILogger>();

builder.Register<EmailLogger>()
  .As<ILogger>()
  .PreserveExistingDefaults(); //keeps console logger as the default

然后得到所有ILoggers:

var loggers = container.Resolve<IEnumerable<ILogger>>();

您不需要做任何特别的事情,只需索要IEnumerable<T>所需的类型。Autofac具有开箱即用的收藏支持,以及可以使用附加功能包装组件的其他适配器

此用法与2.x之前的ImplicitCollectionSupportModule相同,但直接使用。

对于旧版本(0.X-1.4)

两种方式:

1)使用托收登记

var builder = new ContainerBuilder();
builder.RegisterCollection<ILogger>()
  .As<IEnumerable<ILogger>>();

builder.Register<ConsoleLogger>()
  .As<ILogger>()
  .MemberOf<IEnumerable<ILogger>>();

builder.Register<EmailLogger>()
  .As<ILogger>()
  .MemberOf<IEnumerable<ILogger>>();

然后:

var loggers = container.Resolve<IEnumerable<ILogger>>();

这给你一个IEnumerable。

或2)您可以使用ImplicitCollectionSupport模块,这将使代码像Autofac的较新版本一样工作:

builder.RegisterModule(new ImplicitCollectionSupportModule());
builder.Register(component1).As<ILogger>;
builder.Register(component2).As<ILogger>;

然后解决ILogger的集合,而不是寻找全部解决方案。

var loggers = container.Resolve<IEnumerable<ILogger>>();

再次为您提供IEnumerable。


完善。选择选项一,因为它似乎更有效,因为容器“知道”要放入集合中的内容。第二个选项将遍历容器层次结构中的每个注册以查找匹配类型。
crowleym

@ philip-rieck嗨,autofac中的container.resolve是什么意思?如果不使用autofac,则可以通过哪种方式声明Ilogger接口?谢谢...
s_h

1
@sebastian_h如果您不使用autofac,则此答案对您没有意义。你可能想在这里,而不是看:stackoverflow.com/questions/5646820/...
菲利普·里克

@ philip-rieck谢谢,我收到了一个使用它的应用程序,确实我有很多疑问。最好的问候
s_h

哇!这似乎不是很直观。我一直在寻找ResolveAll一种类似于温莎城堡过去的方法(+1)
Leo

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.