72

鉴于以下注册

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>())
{
 ...
}

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

4

2 回答 2

96

对于 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

然后得到所有ILogger的s:

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。

于 2009-09-10T16:03:39.457 回答
60

An update for the sake of the new (2.x) version. All you need now is:

container.Resolve<IEnumerable<I>>();

There's no longer a need for RegisterCollection() or ImplicitCollectionSupportModule - this functionality comes out of the box.

于 2010-08-26T11:55:37.523 回答