Laravel中instance、bind、make方法分析

laravel的Ioc

在学习laravel框架中,不知道依赖注入、控制反转等等这些概念的话,那真的就是小白白啦。

依赖注入

这个名字真的有点吓唬人,首先我们把这名词分开。依赖,谁依赖谁?注入,怎么注入?

class A {
    public function echoA()
    {
        echo "echo A\n";
    }
}

class B {
    public $a;
    public function __construct(A $a) 
    {
        $a = $a;
    }
}
其实这里就是 B依赖 A,A向B里注入了自己。
复制代码

控制反转

既然用到了容器,要想使用一个类中的方法,我不是直接在用的时候 new 类名,而是将 类绑定到容器中,
想要用的时候直接通过容器去实现类中的方法。

instance 方法(Container.php)

public function instance($abstract, $instance)
{
    // app app_path
    $this->removeAbstractAlias($abstract);

    $isBound = $this->bound($abstract);

    unset($this->aliases[$abstract]);

    // We'll check to determine if this type has been bound before, and if it has
    // we will fire the rebound callbacks registered with the container and it
    // can be updated with consuming classes that have gotten resolved here.
    //将 app_path 指定 app_path 实际路径
    $this->instances[$abstract] = $instance;

    if ($isBound) {
        $this->rebound($abstract);
    }

    return $instance;
}
复制代码

make 方法

public function make($abstract, array $parameters = [])
{
    return $this->resolve($abstract, $parameters);
}
复制代码

build 方法

public function build($concrete)
{
    // If the concrete type is actually a Closure, we will just execute it and
    // hand back the results of the functions, which allows functions to be
    // used as resolvers for more fine-tuned resolution of these objects.
    if ($concrete instanceof Closure) {
        return $concrete($this, $this->getLastParameterOverride());
    }

    $reflector = new ReflectionClass($concrete);

    // If the type is not instantiable, the developer is attempting to resolve
    // an abstract type such as an Interface or Abstract Class and there is
    // no binding registered for the abstractions so we need to bail out.
    if (! $reflector->isInstantiable()) {
        return $this->notInstantiable($concrete);
    }

    $this->buildStack[] = $concrete;

    $constructor = $reflector->getConstructor();

    // If there are no constructors, that means there are no dependencies then
    // we can just resolve the instances of the objects right away, without
    // resolving any other types or dependencies out of these containers.
    if (is_null($constructor)) {
        array_pop($this->buildStack);

        return new $concrete;
    }

    $dependencies = $constructor->getParameters();

    // Once we have all the constructor's parameters we can create each of the
    // dependency instances and then use the reflection instances to make a
    // new instance of this class, injecting the created dependencies in.
    try {
        $instances = $this->resolveDependencies($dependencies);
    } catch (BindingResolutionException $e) {
        array_pop($this->buildStack);

        throw $e;
    }

    array_pop($this->buildStack);

    return $reflector->newInstanceArgs($instances);
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享