Dependency injection (DI): Inject a dependent object into an object. The implementation method is generally a container. It is the specific realization of the inversion of control. Inversion of
control (IoC): the way an object obtains dependent objects is reversed, from the active creation method to the passive injection. Is the principle of dependency injection
Scenario: the instantiation of a class needs to depend on the scenario of another class
Injection method and advantages and disadvantages
// Constructor injection (constructor passes parameters)
// Attribute injection (set attributes)
// Interface injection
// Container injection
Container injection code:
class Container {
protected $binds; // 绑定闭包
protected $instances; // 绑定实例
/**
* 向容器中注册服务(往盒子里装对象、或者创建对象的匿名函数)
*
* @param $abstract 服务名称
* @param $conctete 服务体
*/
public function bind($abstract, $concrete) {
// 如果是个闭包则绑定到binds中
if ($concrete instanceof Closure) {
$this->binds[$abstract] = $concrete;
} else {
// 否则绑定到实例数组中
$this->instances[$abstract] = $concrete;
}
}
/**
* 从容器中获取服务(返回对象、或者执行匿名函数来返回对象)
*
* @param $abstract 服务名称
* @param $params 实例化服务所需要传递的参数
*/
public function make($abstract, $params = []) {
// 如果是个实例就返回这个实例
if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
}
array_unshift($params, $this);
// 返回闭包执行结果
return call_user_func_array($this->binds[$abstract], $params);
}
}
class A1 {
public $container;
public function __construct()
{
$this->container = new Container();
}
public function addContainerData($key, $clourse)// 还可以用反射机制
{
$this->container->bind($key, $clourse);
}
public function select($key, $a)
{
$this->container->make($key)->select($a);
}
}
class B1 {
public function select($a) {
echo "i am select {$a}\n";
}
}
class C1 {
public function select($a) {
echo "i am select c1 {$a}\n";
}
}
$A1 = new A1();
$A1->addContainerData('B1', function(){return new B1;});
$A1->addContainerData('C1', function(){return new C1;});
$A1->select('B1', '_hhhh');
$A1->select('C1', '_hhhh_c1');