.NET IoC:从(应用程序)组合根配置库组件
我有一个库处理与数据库后端的交互,我在大多数应用程序中使用该库,现在想要转换为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般来说,您希望应用程序来处理它。您自己说过 - 您希望在应用程序组合根目录中进行 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. :)
根据您的问题标题,我假设您的目标是从组合根配置您的库,但不要求使用应用程序知道如何为其注册所有内容。
使用 Autofac 执行此操作的最简单方法是创建一个或多个模块:
现在,应用程序可以简单地注册模块:
要注册接口的不同实现,您可以在注册模块后简单地提供该注册。 Autofac 采用最后获胜的方法进行注册,这意味着您可以更改模块做出的任何默认决策:
这将导致在
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:
Now, the application can simply register the module:
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:
This will result in
Sha512ConnectionEncryption
being injected whereverIConnectionEncryption
is needed in the application.公共服务定位器也许可以帮助您。它的工作是为多个 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.