• 关于IoC容器的理解


    <?php
    class Container{
        protected $instance; 
        protected $binds;
    
        /**
         * 绑定一个抽象类
         * @param $abstract
         * @param $concrete
         */
    
        public function bind($abstract,$concrete){
    
            if ($concrete instanceof Closure){
                $this->binds[$abstract] = $concrete;
            }else{
                $this->instance[$abstract] = $concrete;
            }
    //        var_dump($this);
            echo "<br />";
        }
    
        /**
         * 制造一个类
         * @param $abstract
         * @param array $parameter
         * @return mixed
         */
    
        public function make($abstract,$parameter = []){
            if (isset($this->instance[$abstract])){ // 检测变量是否已设置并且非 NULL
                return $this->instance[$abstract]; // 如果已经设置了则直接返回
            }
            echo "<pre>";
            var_dump($parameter);
            echo "</pre>";
            echo "<br />";
            echo "<br />";
            echo "<br />";
            echo "<br />";
            array_unshift($parameter,$this); //在数组开头插入一个或多个单元 方便在下一步调用的时候 将之前需要实现的依赖,进行提前处理
            echo "<pre>";
            var_dump($parameter);
            var_dump($this->binds[$abstract]);exit;
            echo "</pre>";
    
            return call_user_func_array($this->binds[$abstract],$parameter); //调用回调函数,并把一个数组参数作为回调函数的参数
        }
    }
    
    // 创建一个容器(后面称作超级工厂)
    $container = new Container;
    
    // 向该 超级工厂 添加 超人 的生产脚本
    $container->bind('superman', function($container, $moduleName) {
        return new Superman($container->make($moduleName));
    });
    
    // 向该 超级工厂 添加 超能力模组 的生产脚本
    $container->bind('xpower', function($container) {
        return new XPower;
    });
    
    //var_dump(function($container) {
    //    return new XPower;
    //});
    
    $container->make("superman",['xpower']);
    

    //首先在工厂的基础上增加一个容器 这个容器用来存储要实现的类 要是那些类当然先要告诉这个容器 也就是提前在容器中注册。
    //通过bind数组的形式 将实现类的匿名函数以key (类名) value(实现方法)注册到容器中
    //在注册的时候需要判断一下 如果是一个继承自匿名类则直接绑定 如果不是匿名类则使用 instances(模块) 变量 存储属性 用于实现一组依赖
    //绑定成功后如果在使用到的地方在进行生产,彻底将模块和实现分离。
    //在需要的时候就进行make,方法接收要是实现的类和模块参数,通过array_unshift调整call_user_func_array的参数顺序 将需要模块提前执行 最后执行在将模块注入到实现的类中

    参考 https://www.insp.top/learn-laravel-container

  • 相关阅读:
    POJ 1703 Find them, Catch them (数据结构-并查集)
    ProductHunt:创业公司产品猎场和秀场
    firedac数据集控件的公共祖先类——TFDAdaptedDataSet
    IDFTP连不上FTP服务器的解决方法
    SQLServer到底支持多少连接数的并发?
    日志
    权限
    DATASNAP中间件调用带OUTPUT参数的存储过程
    连接池中的连接超过数据库端的最大空闲时间
    firedac的TFDStoredProc动态创建并调用存储过程
  • 原文地址:https://www.cnblogs.com/ikai/p/14014938.html
Copyright © 2020-2023  润新知