.NET IoC:从(应用程序)组合根配置库组件

时间:2011-10-03 20:26:40

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

我有一个库处理与我在大多数应用程序中使用的数据库后端的交互,现在想要转换为IoC结构(在内部使用Autofac,但它的用法不应该依赖于特定的IoC容器,甚至不能使用一个人)。如何在没有应用程序处理的情况下以“默认”方式连接库的内部依赖关系,但是如果有必要可以提供其他实现?

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

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

3 个答案:

答案 0 :(得分:3)

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

如果您对DI容器的任何了解不在库中,其他开发人员将能够使用他们选择的容器(或根本没有容器)。

另一方面,你最终会得到类似Rhino Service Bus的东西(大部分)取决于特定的DI容器。如果您的项目是开源的,那么您可能会收到与容器X,版本Y兼容的请求。即使它是封闭源代码,您的团队也可能希望有一天更改容器。

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

答案 1 :(得分:0)

Common Service Locator可能会对您有所帮助。它的工作是为多个IoC容器提供一个通用接口,以便您或您图书馆的其他消费者可以选择要集成的容器。

答案 2 :(得分:0)

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

使用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>();

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