依赖注入框架会带来依赖风险吗?


13

我一直在重构现有系统以使用依赖项注入,并且该工作进展顺利。

一段时间后,我注意到大量内部库变得依赖于我使用的DI框架。结果,整个项目现在都依赖于此第三方框架。

在使所有依赖项依赖于共享库来解耦所有依赖项时,我感到讽刺。

我的第一个反应是围绕依赖关系框架创建包装器库。因此,如果需要,我可以替换此框架。在估计了所涉及的工作之后,我意识到最终的API将类似于现有框架,因此使替换它变得更加困难。所以我放弃了这个主意。

我担心的是,我正在使用的DI框架已过时或需要替换。

使用DI时是否存在减少项目和DI框架之间耦合的开发模式?


4
“不要使用DI框架”模式。尽管我一定想知道您是否正在解决自己实际上没有的问题-更改DI框架的可能性有多大?
奥德2014年

1
@Oded一个好的DI框架应该能够透明地使用代码,但是在某些情况下这是不可能的。然后,您必须在类中使用DI API。在这些情况下,不更改那些类就很难共享或更改DI框架。因为这是我第一次使用该DI框架。我不确定是否需要更换它。
Reactgular 2014年

8
您的系统还取决于电力。我建议您先解耦。
Idan Arye 2014年

3
@MathewFoscarini这不是反模式吗?您可以执行此操作,但是不应该这样做,因为它会混淆依赖关系。
maaartinus 2014年

2
@MathewFoscarini DIFramework.Get<IService>()实际上不是依赖注入;这是一个称为服务定位器的相关模式。许多人不喜欢Service Locator,因为它使您与框架耦合,并且因为它很容易被滥用(例如Singleton)。马丁·福勒(Martin Fowler)撰写了一篇有关这些模式的精彩文章:martinfowler.com/articles/injection.html
本杰明·霍奇森

Answers:


8

您是完全正确的-使用DI框架很可能会使您的代码依赖于该东西。实际上,这太令人惊讶了,因为对于其他所有框架或基础库来说,这都是正确的,尤其是当该库通过在代码中随处使用的某些通用功能支持您的项目时。例如,当您决定使用某个UI框架或Web框架时,一旦基于该库构建了一定数量的代码,此决定就很难更改。当您决定使用特定的(也许是非标准的)String类时,您以后将无法轻易更改该决定。这样的决定是一种体系结构的决定,就像选择某种编程语言并在编写了超过10万行代码之后尝试更改该决定。

只要您的代码符合您的期望并正确维护,让所有代码都依赖于某个框架可能不是问题。但是,如果不是这样,可能会成为一个问题。有一些策略可以解决这种情况:

  • 从您有信心的供应商那里选择一个框架,他可以在几年后为您提供更新和新版本

  • 选择一个具有很少的代码行(和适当的许可证)的开源框架,因此,鉴于供应商从市场上消失,您可以自己进行任何维护

  • 编写自己的框架

  • 只要有供应商就可以适应这种情况,并且当他真正消失时,请选择其他框架,并尝试创建一个适配器,该适配器使用新的适配器来模仿旧的框架

事先创建包装器库的想法根本不是什么新主意,但是我很少看到这种方法可行,因为您将不得不为将来的情况做出假设,而这种情况您不知道它是否或何时会打击您,以及导致什么“新”框架将如下所示。另一方面,几年前,通过应用我上面提到的适配器策略,我们成功地在C ++项目中交换了约120K行代码的完整UI框架。


19

普通的构造函数注入根本不需要框架。您唯一失去的就是能够将依赖项集中在配置文件中。

DI容器是“企业软件”模式,在对象图非常大和复杂时使用。我怀疑95%的应用程序不需要它。


5
我同意小型项目不需要它,但是95%以上的项目可以从中受益
maaartinus 2014年

11
@maaartinus:不必要地增加了复杂性,以最小化收益。
罗伯特·哈维

1
什么啊 这些是我每个班级的统计信息:0.5注释,0.1配置行。那么,您的意思是什么复杂性???
maaartinus 2014年

2
@RobertHarvey:尽管我100%同意您的上述说法,但OP表示他已经引入了DI框架。告诉他“最好不要”并不能真正回答他的问题。
布朗

1
@maaartinus框架自动化程度越高,注入的内容也越复杂。有XML配置文件,构造函数注入,属性注入,自动对象模拟,惰性注入等。等等。这些DI框架可能变得非常复杂。
Reactgular 2014年

0

我认为DI框架不会很快被淘汰。什么会使它过时?

  • 发明新的和更聪明的模式?但是看起来应该像这样,它将需要对代码进行更大的更改。
  • 语言可能会改变吗?更糟。

我会说当前的DI已经足够成熟,我不知道那里发生了什么。您尚未指定语言,因此说到Guice来说,它不是很麻烦,可以与标准Java注释一起使用(也可以将它们自己用于未标准化的事物,但您很少需要它)。它是开源的,使用广泛,并获得Apache许可。可能是什么问题呢?

我敢肯定,更改DI框架比更改任何其他库要容易几个数量级(例如,更改UI意味着要做更多工作)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.