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

发布于 2024-12-07 20:48:16 字数 365 浏览 3 评论 0原文

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

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

为了实现这一目标,我需要在我的图书馆和应用程序中做什么?

I have a library handling interactions with a database backend that I use in most of my applications and now want to convert to an IoC structure (using Autofac internally, but its usage should not depend on a specific IoC container or even on using one at all). How would I go about wiring up the library's internal dependencies in a "default" way without the application having to take care of it, but with the ability to provide other implementations if necessary ?

As an example: The library can store and read connection credentials for different backend servers on/from the user's hard drive. Part of this information, at least the passwords, is encrypted, usually with the default encryption defined in the library - so normally I won't want to care about the details in my application that uses the library. But there might be cases where I need to provide a different encryption algorithm (e.g. through an IConnectionEncryption interface) when calling the logon method from my application.

What do I need to do in my library and in my application to achieve this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傲鸠 2024-12-14 20:48:16

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

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

换句话说,您最终可能会得到类似于 Rhino Service Bus 的东西(大多数情况下)取决于特定的 DI 容器。如果您的项目是开源的,您可能会收到与容器 X、版本 Y 兼容的请求。即使它是闭源的,您的团队有一天也可能想要更改容器。

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

In general you want the application to take care of it. You said it yourself - you want to do the DI container configuration in the application composition root (which is best practice).

If you keep any knowledge of the DI container out of the library, other developers will be able to use their container of choice (or no container at all).

Going the other way, you may end up with something like Rhino Service Bus that (mostly) depends on a particular DI container. If your project is open source, you're likely to get requests for compatibility with container X, version Y. Even if it's closed-source, your team may want to change containers someday.

Hopefully @Mark Seemann can give a canonical answer. :)

第几種人 2024-12-14 20:48:16

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

使用 Autofac 执行此操作的最简单方法是创建一个或多个模块

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应用程序中需要。

I am assuming, based on your question title, that your goal is to configure your library from the composition root, but not require the consuming application to know how to register everything for it.

The easiest way to do this with Autofac is to create one or more modules:

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

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

Now, the application can simply register the module:

// In composition root

builder.RegisterModule<SecurityModule>();

To register a different implementation of an interface, you can simply provide that registration after registering the module. Autofac takes a last-in-wins approach to registrations, meaning you can change any of the default decisions made by the module:

// In composition root

builder.RegisterModule<SecurityModule>();

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

This will result in Sha512ConnectionEncryption being injected wherever IConnectionEncryption is needed in the application.

世界如花海般美丽 2024-12-14 20:48:16

公共服务定位器也许可以帮助您。它的工作是为多个 IoC 容器提供一个通用接口,以便您或库的其他使用者可以选择要集成的容器。

The Common Service Locator might be able to help you. Its job is to provide a common interface for multiple IoC containers to utilize, so you or other consumers of your library can pick which container to integrate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文