php - 为什么在 PHP 框架中使用依赖注入(inject)组件

标签 php symfony dependency-injection singleton php-di

当我第一次看到 PHP-DI、Symfony2 DI 等依赖注入(inject)组件时,我认为有一种方法可以通过一次实例化自动将任何类的实例注入(inject)到任何类中。

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

但我发现,基本上我可以通过两种方式使用依赖注入(inject) 1. 将实例的引用传递给构造函数 2. 创建所有对象所在的容器。该容器可以注入(inject)其他类,但“不推荐这样做”。

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

最佳答案

为什么应该使用依赖注入(inject)而不是单例模式?

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

如果在某个时候我们决定将我们的一个项目从 MySQL 切换到另一种数据库产品怎么办?我们必须修改调用 DatabaseConnection 对象的每个位置,并将其替换为新的实现。或者,我们可以修改类本身 - 但我们仍然想在其他项目中使用原始类,因此我们最终会得到两个具有相同名称的实现,这实际上只是自找麻烦。

那么单元测试呢?当然,我们这样做是因为我们是优秀的开发人员!但是,如果我们对使用数据库的函数进行单元测试,我们不希望测试实际上依赖于数据库,甚至不希望更改数据库中的内容。无法用模拟对象(仅返回静态数据)替换 DatabaseConnection,因为我们的项目与其紧密耦合。

这就是依赖注入(inject)的作用:它有助于防止紧密耦合。如果我们使用 $someObject->setDatabaseConnection($databaseConnection) 注入(inject)连接,我们就可以注入(inject)任何行为类似于原始对象的对象。我们可以注入(inject)模拟对象、继承原始类的替代实现或扩展。

现在,依赖注入(inject)容器只是一个很好的 helper ,可以更轻松地管理对象实例及其依赖项,但执行依赖项注入(inject)时不需要它。

关于php - 为什么在 PHP 框架中使用依赖注入(inject)组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28909977/

相关文章:

php - === php laravel 运算符在 cent os 6.9 中不起作用

.NET Core 2.0 Autofac 注册类 InstancePerRequest 不起作用

使用 Lombok 和 Guice 注入(inject)进行 Java 链继承

php - 如何在全日历议程周 View 上呈现事件-Symfony 3

php - MySQL 上的 Doctrine findBy() 包含带有特殊字符的列

c# - 将 appsettings 配置 DI 添加到 HostBuilder 控制台应用程序

php - 用新值替换数组值

php - 编码 HTML 实体但忽略 HTML 标签 - 在 PHP 中

javascript - php 使用 ajax 或 javascript 处理上传

symfony - 用Twig在for循环内创建一个数组