鉴于以下注册

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,但看不到等效的语法。

最佳答案

对于当前版本的 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 具有开箱即用的集合支持,以及其他 adapters 可以为您的组件包装附加功能。

这与 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。

关于c# - Autofac:解析类型的所有实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1406148/

10-13 04:56