Closed1
Laravelのサービスコンテナのmakeを覗いた時のメモ
make
vendor/laravel/framework/src/Illuminate/Container/Container.php
public function make($abstract, array $parameters = [])
{
return $this->resolve($abstract, $parameters);
}
第一引数には抽象。
resolve
protected function resolve($abstract, $parameters = [], $raiseEvents = true)
{
~~~
$concrete = $this->getConcrete($abstract);
~~~
/**
* Get the concrete type for a given abstract.
*
* @param string $abstract
* @return mixed $concrete
*/
protected function getConcrete($abstract)
{
if (! is_null($concrete = $this->getContextualConcrete($abstract))) {
return $concrete;
}
// If we don't have a registered resolver or concrete for the type, we'll just
// assume each type is a concrete name and will attempt to resolve it as is
// since the container should be able to resolve concretes automatically.
if (isset($this->bindings[$abstract])) {
return $this->bindings[$abstract]['concrete'];
}
return $abstract;
分岐を通り抜けたら、$abstractを返してる。
resolve関数の中。
// We're ready to instantiate an instance of the concrete type registered for
// the binding. This will instantiate the types, as well as resolve any of
// its "nested" dependencies recursively until all have gotten resolved.
if ($this->isBuildable($concrete, $abstract)) {
$object = $this->build($concrete);
} else {
$object = $this->make($concrete);
}
isBuildableだったらbuildする。
もしBuildablじゃなかった場合、具体クラスを引数にまたmakeの処理を通る。
つまり、コンテナに抽象と具体を登録してる場合、2回この関数を通ることになるのかなあ??。一回目は抽象クラスから具体クラスを取得するため。二回目は具体クラスを生成するため。
protected function isBuildable($concrete, $abstract)
{
return $concrete === $abstract || $concrete instanceof Closure;
}
抽象===具体orクロージャー普通の場合は、buildable。
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);
}
上記の抜き出し
$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;
}
コンストラクターがnullだったら普通にnewしてる!!!
コンストラクターが存在してたら、以下を通ってるっぽい
またresolveの抜き出し
$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);
コンストラクタの引数をとってきて、それをまたコンテナ経由で生成?
生成した$instancesを引数に新たなインスタンスを生成して返す。っていう流れみたい。
このスクラップは2022/02/15にクローズされました