// 容器类,将接口与实现绑定
    class Container{
    // 保存与接口绑定的闭包,
    // 闭包必须能够返回接口的实例。
    protected $bindings = [];

    1. // 为某个接口绑定一个实现,有两种情况: <br /> // 第一种是绑定接口的实现的类名;


    // 第二种是绑定一个闭包,这个闭包应该返回接口的实例。
    // 不管哪种情况,实例化操作都是调用 build() 方法完成。
    // 第二种情况,主要是为了能够在实例化前后进行额外的操作,
    // 实例化的逻辑就书写在闭包中。
    public function bind($abstract, $concrete = null) {
    // 如果提供的参数不是闭包,而是一个类,
    // 则构建一个闭包,直接调用 build() 方法进行实例化
    if (! $concrete instanceof Closure) {
    // 调用闭包时,传入的参数是容器本身,即
    $this $concrete = function ($c) use ($concrete) { return $c->build($concrete); }; }
    $this->bindings[$abstract] = $concrete;
    }

    // 生成指定接口的实例
    


    public function make($abstract) {
    // 取出闭包
    $concrete = $this->bindings[$abstract];
    // 运行闭包,即可取得一个实例
    return $concrete($this);
    }

    public function build($class)
    {
    


    // 取得类的反射
    $reflector = new ReflectionClass($class);

        // 检查类是否可实例化
    


    if (! $reflector->isInstantiable()) {
    // 如果不能,意味着接口不能正常工作,报错 echo $message = “Target [$class] is not instantiable”; }

        // 取得构造函数的反射
    


    $constructor = $reflector->getConstructor();
    // 检查是否有构造函数
    if (is_null($constructor)) {
    // 如果没有,就说明没有依赖,直接实例化
    return new $class;
    }

        // 取得包含每个参数的反射的数组
    


    $parameters = $constructor->getParameters();
    // 返回一个真正的参数列表,那些被类型提示的参数已经被注入相应的实例
    $realParameters = $this->resolveDependencies($parameters);
    return $reflector->newInstanceArgs($realParameters);
    }

    //解决依赖 支持数组 注入

    protected function resolveDependencies($parameters){
    


    $realParameters = [];
    foreach($parameters as $parameter) {
    // 如果一个参数被类型提示为类 foo,
    // 则这个方法将返回类 foo 的反射
    $dependency = $parameter->getClass();
    if(is_null($dependency)) {
    $realParameters[] = NULL;
    } else {
    $realParameters[] = $this->make($dependency->name);
    }
    }

        return (array)$realParameters;
    


    }

    }

    原文简化版
    https://learnku.com/articles/4076/how-to-understand-laravels-ioc-container