1

假设我有实现 IEmailService 的 EmailService。并且 EmailService 对 ILoggingService 具有构造函数依赖性。现在鉴于我有几个 ILoggingService 的实现,可以实现这样的事情:

<component service="IEmailService, MyInterfaces" type="EmailService, MyLib">
  <parameters>
    <parameter name="loggingService" value="LoggingService, MyLib" />
  </parameters>
</component>

我已经研究过为注册类型命名,但到目前为止找不到如何从 XML 配置中使用它们的示例。

简而言之,我想使用 XML 配置来指定哪个具体的记录器实现被注入。

4

1 回答 1

3

Autofac 中的 XML 配置更多地针对 80% 的用例,而不是完全实现 Autofac 在 XML 形式中的灵活性。Autofac 建议使用其模块机制进行配置。模块与 XML 配置相结合,可以成为实现您想要完成的目标的一种非常强大的方式,并且仍然具有根据需要在依赖项之间切换的灵活性。

首先,创建一个进行所需注册的 Autofac 模块:

public class EmailModule
{
  protected override void Load(ContainerBuilder builder)
  {
    // Register a named logging service so we can locate
    // this specific one later.
    builder.RegisterType<LoggingService>()
           .Named<ILoggingService>("emailLogger");

    // Create a ResolvedParameter we can use to force resolution
    // of the constructor parameter to the named logger type.
    var loggingServiceParameter = new ResolvedParameter(
      (pi, ctx) => pi.Name == "loggingService",
      (pi, ctx) => ctx.ResolveNamed<ILoggingService>("emailLogger"));

    // Add the ResolvedParameter to the type registration so it
    // knows to use it when resolving.
    builder.RegisterType<EmailService>()
           .As<IEmailService>()
           .WithParameter(loggingServiceParameter);
  }
}

请注意,注册有点复杂,因为您需要非常具体的解决方案。

现在在 XML 配置中,注册该模块:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section
      name="autofac"
      type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
  </configSections>
  <autofac>
    <modules>
      <module type="EmailModule, MyAssembly" />
    </modules>
  </autofac>
</configuration>

当您想要切换配置时,注册一个不同的模块而不是摆弄特定的组件注册表。

代码免责声明:我是从内存中编写语法,我不是编译器,所以你可能需要做一些调整......但前提是成立的。隔离模块中的复杂性,然后注册您的模块。

于 2012-05-18T15:11:19.613 回答