Dependency injection (DI), inversion of control and containers

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');

 

Guess you like

Origin blog.csdn.net/weixin_38230961/article/details/106122047