【问题标题】:.NET IoC: Configure library components from (application) composition root.NET IoC:从(应用程序)组合根配置库组件
【发布时间】:2011-11-30 05:10:46
【问题描述】:

我有一个库处理与我在大多数应用程序中使用的数据库后端的交互,现在想要转换为 IoC 结构(在内部使用 Autofac,但它的使用不应依赖于特定的 IoC 容器,甚至不依赖于使用一个)。我将如何以“默认”方式连接库的内部依赖项,而无需应用程序处理它,但在必要时能够提供其他实现?

例如:库可以在用户硬盘上存储和读取不同后端服务器的连接凭据。这些信息的一部分,至少是密码,是加密的,通常使用库中定义的默认加密——所以通常我不想关心使用库的应用程序中的细节。但在某些情况下,当从我的应用程序调用登录方法时,我需要提供不同的加密算法(例如通过IConnectionEncryption 接口)。

我需要在我的库和应用程序中做什么才能实现这一目标?

【问题讨论】:

  • 您是否需要在启动时应用不同的实现作为选项,或者由于上下文的变化而在运行时动态应用?
  • @MarcL。仅在启动时;如果应用程序提供了自己的实现,我希望在整个过程中都使用它。
  • @MarkSeemann 我后来发现了这个问题,我猜你的回答就图书馆的 API 而言已经说明了一切。但是,我希望能够通过 IoC 容器处理库的内部依赖项和默认实现,尽管这似乎很困难,因为它不会有一个点,最终调用所有代码可以作为我的组合根(仅适用于图书馆;我希望它在外部与容器无关)。

标签: .net dependency-injection inversion-of-control autofac


【解决方案1】:

一般来说,您希望应用程序来处理它。您自己说过 - 您想在应用程序组合根目录中进行 DI 容器配置(这是最佳实践)。

如果您将 DI 容器的任何知识保留在库之外,其他开发人员将能够使用他们选择的容器(或根本不使用容器)。

反过来,你可能会得到类似Rhino Service Bus 的东西,它(大部分)依赖于特定的 DI 容器。如果您的项目是开源的,您很可能会收到与容器 X、版本 Y 兼容的请求。即使它是闭源的,您的团队也可能希望有一天更改容器。

希望@Mark Seemann 能给出一个规范的答案。 :)

【讨论】:

  • +1 这很好地解释了您不想封装特定容器的原因。有关执行此操作的选项,请参阅我添加到问题中的链接。
【解决方案2】:

根据您的问题标题,我假设您的目标是从组合根目录配置您的库,但不要求使用应用程序知道如何为其注册所有内容。

使用 Autofac 最简单的方法是创建一个或多个 modules:

public class SecurityModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register<Sha256ConnectionEncryption>.As<IConnectionEncryption>();

        // ...other security-related registrations...
    }
}

现在,应用程序可以简单地注册模块:

// In composition root

builder.RegisterModule<SecurityModule>();

要注册接口的不同实现,您只需在注册模块后提供该注册即可。 Autofac 对注册采用“最后获胜”的方法,这意味着您可以更改模块做出的任何默认决策:

// In composition root

builder.RegisterModule<SecurityModule>();

builder.Register<Sha512ConnectionEncryption>().As<IConnectionEncryption>();

这将导致在应用程序中需要IConnectionEncryption 的任何地方注入Sha512ConnectionEncryption。

【讨论】:

    【解决方案3】:

    Common Service Locator 或许可以帮助您。它的工作是为多个 IoC 容器提供一个通用接口以供使用,以便您或您的库的其他消费者可以选择要集成的容器。

    【讨论】:

      猜你喜欢
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      相关资源
      最近更新 更多