【问题标题】:Autofac: Resolve all instances of a TypeAutofac:解析类型的所有实例
【发布时间】:2009-09-10 15:57:20
【问题描述】:

鉴于以下注册

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?
  • 我真正喜欢 Autofac 的地方是能够通过 lamda 表达式表达动态组件构造。通过使用表达式而不是自动装配,当容器解析类型时,误解容器正在“做什么”的空间更少(注意:如果您愿意,autofac 支持自动装配)。最后,Windsor API 变得如此庞大,以至于它可以满足每一种可能性,它给人一种复杂的印象,而 IOC 作为一个概念实际上非常简单。并不是说我永远不会再使用 Windsor,只是尝试其他选项。
  • 我考虑过从温莎搬到 Autofac。 Windsor 的 API 令人困惑。

标签: c# autofac


【解决方案1】:

对于 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&lt;T&gt;。 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。

【讨论】:

  • 完美。选择选项一,因为它似乎更有效,因为容器“知道”将什么放入集合中。第二个选项遍历容器层次结构中的每个注册以寻找匹配的类型。
  • @philip-rieck 嗨,autofac 中的 container.resolve 是什么意思?如果不使用autofac,可以通过哪种方式声明Ilogger接口?谢谢...
  • @sebastian_h 如果您不使用 autofac,则此答案对您没有任何意义。你可能想看看这里:stackoverflow.com/questions/5646820/…
  • @philip-rieck 谢谢,我收到了一个使用它的应用程序,我确实有很多疑问。最好的问候
  • 哇!这似乎不是很直观。我正在寻找一种类似于过去温莎城堡 (+1) 的 ResolveAll 方法
【解决方案2】:

为了新的 (2.x) 版本而进行的更新。你现在只需要:

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

不再需要RegisterCollection()ImplicitCollectionSupportModule - 此功能开箱即用。

【讨论】:

    猜你喜欢
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多