当我第一次看到依赖注入组件如PHP-DI,Symfony2 DI等时,我有一种方法可以自动将任何类的实例注入到任何实例化的任何类中。
所以
1.在根类中创建实例,如$foo = new Foo()
2.然后我可以在任何对象(如全局单例)中使用此实例,而不传递对我想要调用的类的构造函数或方法的引用。
但我发现,基本上我可以用两种方式使用依赖注入 1.将实例的引用传递给构造函数 2.创建所有对象所在的容器。这个容器可以注入其他类,但是#34;这不推荐"。
由于这两种方法都可以在纯PHP中轻松完成,第一种方法是明确的,第二种方法可以用静态属性来解决,那么为什么要使用PHP-DI或Symfony2进行这项工作?
答案 0 :(得分:2)
为什么要对Singleton模式使用依赖注入?
假设我们有一个名为DatabaseConnection
的Singleton对象,它为我们包装了一个与MySQL数据库的连接,并做了一些其他整洁的事情,谁知道呢。因为重用代码是件好事,所以我们在很多项目中使用这个对象。
如果在某些时候我们决定将我们的一个项目从MySQL切换到另一个数据库产品怎么办?我们必须修改我们调用DatabaseConnection
对象的每个地方,并将其替换为我们的新实现。或者,我们可以修改类本身 - 但是我们仍然希望将原始类与其他项目一起使用,因此我们最终会使用两个具有相同名称的实现,这实际上只是在寻找麻烦。
那么单元测试怎么样?当然,我们这样做是因为我们是优秀的开发人员!但是如果我们对使用数据库的函数进行单元测试,我们就不希望测试实际上依赖于数据库甚至改变那里的东西。没有办法用模拟对象(只返回静态数据)替换DatabaseConnection
,因为我们的项目与它紧密耦合。
依赖注入的作用:它有助于防止紧密耦合。如果我们使用$someObject->setDatabaseConnection($databaseConnection)
注入连接,我们可以在那里注入任何与原始对象相似的对象。我们可以注入继承原始类的模拟对象,替代实现或扩展。
现在,依赖注入容器只是一个很好的帮助,可以更轻松地管理对象实例及其依赖项,但执行依赖注入不需要它。