依赖注入的思想就是即用即实例,反转类与类之间的控制关系,实现由调用类A类控制后续的依赖关系,这样可以让B类随意的更改所需依赖和实例化的类(C类或D类),达到解耦的目的。
三、常用的依赖注入方式:
1、构造方法注入;2、set属性注入;3、静态工厂方法注入;
上述的例子使用的就是构造方法注入的方式,将对象作为参数传递到构造方法中;同样的set属性注入也是相类似的方法,不同的仅仅是在set一个类的成员的属性时传递这个对象参数,在此就不一一举例了。
除此之外,还有静态工厂方法注入的方式,这种方法与静态工厂方法类似。
我们知道静态工厂方法就是通过一个类来管理需要实例化的多个相似的类,该类会定义一个方法用于获取需要实例化的对象,而具体要实例化哪个对象就依赖于传递进来的对象名参数了。
对于静态工厂方式的注入,与一般的静态工厂方法不同之处在于这个传进来的参数是一个已经实例化过的对象。
<?php class IoC { protected static $registry = []; public static function bind($name, Callable $resolver) //传入类名和类对象实例 { static::$registry[$name] = $resolver; } public static function make($name) //静态工厂方法 { if (isset(static::$registry[$name])) { $resolver = static::$registry[$name]; return $resolver(); //实例化 } throw new Exception('Alias does not exist in the IoC registry.'); } }
总而言之,三种方式传递的都是实例化对象,只是不同之处在于传递的位置分别为构造方法、set属性、静态工厂方法而已。
四、依赖注入容器(Ioc容器)
大多数时侯,在使用依赖注入方式解耦组件时,并不需要用到容器。
当一段程序需要实例化的类太多或者依赖太多的时候,重复依赖注入的代码是比较繁琐的事情,例如以下情况:
当产生以上关系的时候,依赖注入的代码会比较混乱,而且存在重复,更有可能在调用一个一般方法时new一个不需要的类,产生冗余。
此时需要使用容器,使用依赖注入容器后的思路是应用程序需要到A类,就从容器内取得A类。具体是容器创建C类,再创建B类并把C注入,再创建A类,并把B类注入,应用程序调用A类方法, A类调用B类方法,接着做些其它工作.总之容器负责实例化,注入依赖,处理依赖关系等工作。