【发布时间】:2011-06-04 17:50:30
【问题描述】:
很长一段时间以来,我们有幸拥有通用服务定位器 (CSL) 来解析来自未知来源的服务。但是,从一开始就没有任何与容器无关的解决方案来注册这些服务。我们一直面临着必须将我们的组合代码耦合到特定 IoC 容器的问题,此外,还要致力于在整个应用程序中使用该容器。
我觉得我可能在这里尝试实现不可能的目标,但是有人对如何实现 Common Service Registry (CSR) 有任何想法吗?
我最初的想法是使用MEF来解析各种IContainerIntegrators(每种容器技术一个类),然后使用MEF来解析各种IXXXContainerBindings(每种技术一个接口)。然后,用户可以围绕容器绑定开发应用程序,只需将其绑定放入 BIN 目录即可实现插件架构。如果他们想使用新的容器技术,那么他们只需要开发一个新的IContainerIntegrator 类和随附的IXXXContainerBinding,然后他们将使用它来编写自己的绑定。在应用程序启动时,CSR 使用 ServiceLocatorAggregator 类将所有容器实例聚合到一个 CSL 中。
我已经完成了这项工作,但面临以下问题:
- 任何调用当前(不完整)容器的绑定都是不稳定的,因为之前的注册可能被后续的绑定覆盖。这包括需要解析对象以做出注册决定的绑定(即“如果存在则绑定它”)。
- 可能存在两个公开同一组服务的绑定。但是,我们希望“交错”这些注册。例如。 '我想要来自绑定 X 的服务 A 和 C,以及来自绑定 Y 的服务 B 和 D'。
- 在自动连接所请求服务的依赖项时,容器会自行解析服务。例如。 'container.Bind
.To ()' 将自动注入从 'container' 解析的服务的实现,而不是来自聚合服务定位器。
如果我完全错过了这里的要点,请对我大喊大叫,但这不是最解耦的依赖管理解决方案吗?会不会很好?我即将开始一个带有插件架构的大型企业项目。我不想提交到特定的 IoC 容器。
(p.s. 这个问题是关于支持发现的与容器无关的组合。请不要就 SL 与 DI 进行辩论。SL 用于组合,这就是为什么我在这里大量引用它的原因)。
【问题讨论】:
-
我认为不依赖于一个特定的 IoC 容器是有意义的。但是同时使用其中的几个?对我来说,这听起来是个坏主意。
-
我们还有哪些其他选择?我不认为我们可以两者兼得。 Application Vendor 可能使用 Autofac,但 Plugin Vender A 可能使用 Ninject, Plugin Vendor B 可能使用 Castle。
-
我认为插件内部使用什么并不重要,只要您的插件 API 直接提供所有必需的。
-
所以回答Dependency Inject (DI) “friendly” library 可能对你有用。
-
@svick - 不确定我是否理解你的意思。绑定(或插件)可以用新的实现替换现有的实现。例如。我们的应用程序可能依赖于 ISearchProvider。默认绑定可能会向 LuceneProvider 注册,但稍后会发布一个新的绑定来注册 GoogleProvider。我的意思是,这两个绑定不应该使用相同的容器技术……但目前它们确实如此。
标签: c# .net dependency-injection inversion-of-control ioc-container