为什么我们需要依赖注入的框架?[关闭]


42

我一直在阅读有关控制反转原理和依赖注入作为其实现的更多信息,并且我确信我理解它。

似乎基本上是在说“不要在类中声明类成员的实例化”。相反,实例化应该通过构造函数传递并分配;从外部来源“注入”到班级中。

如果就这么简单(看起来如此),为什么我们需要像spring或guice这样的带有注释的框架?我在这里缺少基本的东西吗?我真的很难理解依赖注入框架的用途。

编辑:关于可能的重复,我相信我的问题更加独特,因为它询问的是一般的DI框架,而不仅仅是Spring。Spring不仅是一个DI框架,所以有很多人想要使用Spring的原因都与DI无关。



11
它们对于将错误转移到运行时而不是编译时很有用。

1
@den我们为什么要这样做?这似乎很快就失败了
该用户需要帮助

Answers:


26

我们不需要框架。即使对于较大的项目,也完全可以手动实现依赖项注入。

另一方面,使用框架更容易,特别是基于注释或自动检测依赖项的框架,因为它使过程更简单:如果我决定在类中需要新的依赖项,那么我要做的就是添加将其传递给构造函数(或声明一个setter),然后注入对象-我不需要更改任何实例化代码。

同样,框架通常包含其他有用的功能。例如,Spring包含一个面向方面的编程的有用框架,包括声明性事务划分(非常方便)和各种适配器实现,这些实现使许多第三方库更易于集成。


8
打钉子在头上。我们并不需要他们。它们只会使大型项目的工作变得更轻松。坦白地说,我发现框架比小型项目更麻烦。我鼓励OP不要将依赖注入与支持它的框架相混淆。
RubberDuck

1
说得好。当别人制造出又好又圆的轮子时,为什么还要重新发明轮子呢?
jwenting

就是这样 除了我不需要更改任何实例化代码 -当然,没有实例化代码 ;-)
Mathieu Guindon 2015年

好像您的DI库很烂。好的人可以猜测该类使用反射实例化。
Florian Margaine 2015年

2
任何使用反射进行运行时处理的人都做错了。反射是仅仅因为您可以做某事并不意味着您应该做的那些技术之一。
gbjbaanb 2015年

12
  1. 为什么我们完全需要DI(依赖注入)?

    DI机制将对象生产与对象消耗分开。对象所需的依赖关系从外部透明地传递。该机制的优点很明显:您可以随时交换依赖关系,例如,出于测试目的使用Null对象

  2. 怎么做?

    有几种方法可以实现目标:

    • 通过构造函数注入注入依赖
    • 通过吸气剂/设定剂注入
    • 接口注入
  3. 我们需要DI框架吗?

    一点都不。您可以简单地手动将所有实例传递给其他对象。如果您的应用程序很小,则不需要弹簧容器。

    但另一方面,框架可以帮助您管理对象:

    • 它们帮助您连接复杂的对象关系。您无需编写任何样板代码,即可生成实例并将其传递给适当的对象

    • 它们可以帮助您控制何时创建对象:您可以在应用程序引导过程中创建实例,但是在某些情况下,仅在需要时才最好进行延迟创建

    • 它们可帮助您控制创建多少个实例:每个应用程序生命周期一个实例或每个请求一个实例(如果您正在进行网络编程)

如果您的项目大小合适-如果您需要编写更少的样板代码-使用(DI-)框架完全有意义。利弊多于利弊。


2
您可以完全不使用框架而使用DI库。
Florian Margaine 2015年

5

在春季,这主要是为了方便。

如果您有一个类TopLevel,它是构造类MiddleLevel,并且构造了类LowLevel,并且您意识到需要在上LowLevel添加新的构造函数参数,则还必须将其添加到TopLevel和上MiddleLevel,以便在需要时MiddleLevel构造一个LowLevel值。以便可以将其传递给其构造函数。对于spring,您只需添加注释。

另外,使用spring,可以在外部配置文件而不是xml中定义依赖项,并且据称这使您能够“不更改任何代码”地使用完全不同的布线生成新系统。(恕我直言,这是完全错误的,因为更改xml与更改代码并没有太大的区别,实际上,代码通常比xml具有更好的错误检查和类型检查。)

另一件事是,许多人害怕构造函数。他们不了解它们,他们不喜欢它们,他们宁愿不使用它们。


3
通常都同意,尤其是XML注释。恕我直言,害怕构造函数可能是使用DI框架的一个不好的原因。
罗伯特·哈维

2
恕我直言,害怕构造函数是远离编程的一个很好的理由。C-:=
Mike Nakis 2015年

5
但是,相对于工厂(静态或其他),这有何优势?(这是您可以适当使用的选项的优势,而春天似乎是完全不公平的选择)
理查德·

@RichardTingle Spring可能代表着优势,这主要是因为它除了DI之外还具有其他所有功能,因为显然,您可以通过许多其他方式实现DI,静态工厂就是其中之一。(这是最酷的方法之一,但仍然是。)但是问题是,是否必须使用spring才能实现DI,这就是我一直在尝试的答案:基本上,没有必要,只是一个方便。
Mike Nakis 2015年

这是DI不是什么的一个例子。“ TopLevel”不应创建MiddleLevel,但在构造时TopLevel作为构造函数的参数应接收它。同样,MiddleLevel应该LowLevel在其构造函数中接收一个。
清晰的

1

几年前,我写了一个程序来监视我曾经工作过的公司的网页,Web Portlet,甚至某些数据库表。我希望它具有足够的灵活性,以使用户可以指定将运行哪些监视器以及使用哪些参数(URL,登录名,成功条件等)。因此,我将其编写为从XML文件读取,并使用Java反射实例化指定的类并使用setter方法设置指定的参数。

后来我发现Spring将为您做同样的事情,甚至更多。

所以我的情况是

  1. 使用依赖项注入框架有助于使程序更灵活,并更容易指定其运行方式(当然,应在定义明确的参数范围内)。

  2. 使用第三方DI框架使您不必重新发明轮子。


4
您能否解释一下为什么在XML而不是Java文件中定义使用哪个具体类更好。那是我从来不了解的东西。
理查德·廷格

1
这不是什么灵丹妙药,但是使用配置文件的一个优点是,至少从理论上讲,它们比代码更容易编辑。另外,正在运行您的程序但无权访问您的源代码的用户可以更改它们。在我给出的原始依赖项注入程序的示例中,有时我会更改XML配置文件,以便即使我是编写该程序的人也可以更改程序的运行方式。如果您不需要外部可配置性,则使用代码可以更轻松地实现。我还有另一项工作,我们完成了代码中的所有DI,并且效果很好。
Paul J Abernathy,2015年
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.