【发布时间】:2011-09-14 11:25:58
【问题描述】:
我目前正在使用依赖注入。实际上,这涉及到 UI 层(例如 Web 应用程序),其中包括一个 DI 容器,该容器具有关于它将使用的接口的一大堆数据,以及每个接口要使用的实现。
但是,由于需要满足依赖关系,DI 容器还需要了解它原本不需要访问的接口和类。例如:
UI 层需要使用IWidgetManager 接口。配置的实现是ConcreteWidgetManager。这是在 DI 容器中注册的。
ConcreteWidgetManager 依赖于 IWidgetRepository。所需的实现是ConcreteWidgetRepository。因此DI容器也必须知道IWidgetRepository和ConcreteWidgetRepository。
如果我只是硬编码ConcreteWidgetManager 对ConcreteWidgetRepository 的依赖,那么ConcreteWidgetRepository 可以在内部进行,因此对我的UI 层不可见。没有任何 UI 代码可以绕过管理器层并直接与存储库层一起工作。
因此,从 UI 层的角度来看,尽管 DI 的使用在许多方面都是一种很棒的模式,但似乎破坏了封装。
我的想法是否正确,有什么办法可以缓解这种情况吗?
【问题讨论】:
-
答案是肯定的,DI 确实打破了封装。它是 stackoverflow.com/questions/1005473/… 的副本,另请参阅 bryancook.net/2011/08/…
-
ConcreteWidgetRepository如何对 UI 层可见?框架配置中提到它的事实并不意味着它是“可见的”,除非您的 UI 代码具有对IWidgetRepository的自动关联引用。这是一个编码问题,它完全等同于您的 UI 代码,其中包含对ConcreteWidgetRepository的硬编码引用 -
@parsifal - DI 容器是 UI 层的一部分。如果它需要知道
ConcreteWidgetRepository(它确实需要将一个注入ConcreteWidgetManager),那么该知识也可以在UI 层的其他地方免费获得。 -
@David - 在我看来,DI 容器 是 应用程序:它将 UI 与业务逻辑相关联,并连接任何内部依赖项,但它不是 部分。
-
@parsifal - 我不知道你在什么平台上开发,所以我不太确定如何提出问题,所以我将把它交给你 .NET 风格。那么你如何创建你的解决方案呢? DI 容器与 UI 项目(例如 Web 应用程序)在不同的项目中?
标签: design-patterns dependency-injection encapsulation