为什么在 PHP 个框架中使用依赖注入组件

Why to use Dependency Injection components in PHP frameworks

当我第一次看到 PHP-DI、Symfony2 DI 等依赖注入组件时,我想,有一种方法可以自动将任何 class 的实例注入到任何一个实例实例化。

所以 1. 在根 class 中创建实例,如 $foo = new Foo() 2. 然后我可以在任何对象(如全局单例)中使用此实例,而无需传递对我想调用的 class 的构造函数或方法的引用。

但我发现,基本上我可以通过两种方式使用依赖注入 1.将实例的引用传递给构造函数 2.创建所有对象所在的容器。此容器可以注入其他 classes,但 "This is not recommended".

由于这两种方法都可以在纯 PHP 中轻松完成,第一种很清楚,第二种可以用静态属性解决,所以为什么要使用 PHP-DI 或 Symfony2 来完成这项工作?

为什么要在单例模式上使用依赖注入?

假设我们有一个名为 DatabaseConnection 的 Singleton 对象,它为我们包装了到 MySQL 数据库的连接,并做了一些其他巧妙的事情,谁知道呢。因为重用代码是一件好事,所以我们在很多项目中都使用了这个对象。

如果在某个时候我们决定将我们的一个项目从 MySQL 切换到另一个数据库产品怎么办?我们将不得不修改我们调用 DatabaseConnection 对象的每个地方,并将其替换为我们的新实现。或者,我们可以修改 class 本身——但我们仍然想将原始的用于其他项目,所以我们最终得到 两个同名的实现 这是自找麻烦,真的。

那么单元测试呢?当然,我们这样做是因为我们是优秀的开发人员!但是如果我们对一个使用数据库的函数进行单元测试,我们不希望测试实际依赖于数据库或者甚至改变那里的东西。无法用模拟对象(只是 returns 静态数据)替换 DatabaseConnection,因为我们的项目与它紧密耦合。

这就是依赖注入的作用:它有助于防止紧耦合。如果我们用 $someObject->setDatabaseConnection($databaseConnection) 注入连接,我们可以在那里注入任何行为类似于原始对象的对象。我们可以注入继承原始 class.

的模拟对象、替代实现或扩展

现在 依赖注入容器 只是一个很好的帮手,可以更轻松地管理对象实例及其依赖关系,但不需要进行依赖注入。