依赖注入(DI)是面向对象编程中最容易被误解的概念之一。混乱之处很多,涉及术语、目的和机制。它应该被称为依赖注入、控制反转,甚至是第三方连接吗?依赖注入的目的仅仅是支持单元测试,还是有更广泛的目的?DI是否与服务位置相同?是否需要DI容器?
有很多讨论依赖注入的博客文章、杂志文章、会议演示等等,但不幸的是,它们中的许多使用了相互矛盾的术语或给出了糟糕的建议。这在所有方面都是正确的,即使是像微软这样有影响力的大公司也增加了困惑。
事情不必是这样的。在这本书中,我提出并使用了一个一致的术语,我希望其他人也能采用。在很大程度上,我采用并澄清了其他人定义的现有术语,但偶尔也会添加一些以前没有的术语。这极大地帮助了我制定依赖注入的范围或边界的规范。
所有不一致和糟糕建议背后的一个潜在原因是依赖注入的边界相当模糊。DI在哪里结束,其他面向对象的概念从哪里开始?我认为在DI和编写好的面向对象代码的其他方面之间划清界限是不可能的。要谈论依赖注入,我们必须引入其他概念,如固体代码和干净代码。我觉得如果不触及其他一些主题,我就不能可信地写出DI。
本书的第一部分帮助您理解依赖注入相对于软件工程其他方面的地位–可以这么说,是把它放在地图上。
第一章让你快速了解DI,包括它的目的、原则和好处,并为本书的其余部分提供了一个范围大纲。如果你想了解什么是DI,以及为什么你应该对它感兴趣,这就是开始的地方。这一章假定你以前没有DI的知识,但即使你已经知道它,你可能仍然想读它–它可能会变成与你预期不同的东西。
第一章专注于大局,没有涉及很多细节。另一方面,第二章完全是为一个大的例子保留的。这个例子旨在让你对DI有一个更具体的感觉。它分为两部分,几乎是一个叙事的形状。为了将DI与更 "传统 "的编程风格进行对比,本章首先展示了一个典型的、紧密耦合的示例程序的实现,然后用DI重新实现了它。
第一部分的第三章,也是最后一章,介绍了DI 容器的概念,并解释了它是如何融入DI的全局的。 我从总体上讨论了DI,虽然我提供了一些代码例子来证明一个典型的DI 容器是如何工作的,但这一章的目的不是解释具体的API细节。 第三章的主要内容是说明DI 容器是一个(非常有用的)可选工具。在不使用DI 容器的情况下,利用DI是完全可能的,所以第二和第三部分或多或少地忽略了DI 容器,而是以一种与容器无关的方式讨论DI。然后,在第四部分,我们转向DI 容器来剖析六个特定的容器。
第一部分为本书的其余部分建立了背景。它针对的是之前没有任何DI知识的读者,但有经验的DI从业者也可以通过略读这几章来感受全书中使用的术语。 在第一部分结束时,你应该对词汇和总体概念有一个牢固的掌握,即使一些具体的细节还有些模糊。 没关系,随着你的阅读,这本书会变得更加具体,所以第2、3和4部分应该能回答你在阅读第1部分后可能会遇到的问题。