前置き
Laravel5.6のコードを読んでいきます。
DIだとか依存性注入だとかいうけど、実際にはどこで注入してんだよ!ってのが気になったので調べました。
Let's コードリーディング!!!
はじめに、LaravelにはApplicationクラスというのがあります。
bootstrap/app.php
でインスタンスを作ってるやつです。
bootstrap/app.php
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
こいつです。こいつをみてみましょう。
vendor/laravel/framework/src/Illuminate/Foundation/Application.php
class Application extends Container implements ApplicationContract, HttpKernelInterface
{
}
Containerクラスを継承してることからわかるように、このApplicationクラスはサービスコンテナ(=DIコンテナ)です。このContainerクラスの中にサービスをインスタンス化するメソッドがあります。
vendor/laravel/framework/src/Illuminate/Container/Container.php
public function make($abstract, array $parameters = [])
{
return $this->resolve($abstract, $parameters);
}
こいつです。そのまんまの名前なのでわかりやすいです。
さて、順に追っていきましょう。resolveメソッドをみてみます。
以下、関連する場所だけ抜粋。
vendor/laravel/framework/src/Illuminate/Container/Container.php
protected function resolve($abstract, $parameters = [])
{
~~~~
if ($this->isBuildable($concrete, $abstract)) {
$object = $this->build($concrete);
} else {
$object = $this->make($concrete);
}
~~~~
return $object;
}
makeを辿ってここまできたのでbuildの方を追ってみます(適当)。
例によって関係ありそうな箇所を抜粋してみます。
vendor/laravel/framework/src/Illuminate/Container/Container.php
public function build($concrete)
{
if ($concrete instanceof Closure) {
return $concrete($this, $this->getLastParameterOverride());
}
$reflector = new ReflectionClass($concrete);
$constructor = $reflector->getConstructor();
$dependencies = $constructor->getParameters();
$instances = $this->resolveDependencies(
$dependencies
);
return $reflector->newInstanceArgs($instances);
}
buildメソッドの引数、$concrete
にはクラス名かクラスのオブジェクト、もしくはClosureオブジェクトが入ります(たぶん)。
Closureだった場合は実行してreturnしてます。
そうでない場合、ReflectionClassのオブジェクトをつかって依存関係を解決していきます。
ReflectionClassについてはこちらをご参考ください。
あとは順番に読んでいきましょう。
- ReflectionClassオブジェクトを利用して、注入先クラス(クライアント)のコンストラクタを取得
- コンストラクタのパラメータを取得
- resolveDependenciesメソッドで注入する依存オブジェクトのインスタンスを作成(プリミティブなケースは説明を割愛。resolveDependenciesメソッドを読んでみてください。)
- ReflectionClassオブジェクトを利用して先ほどインスタンス化した依存オブジェクトを引数に注入先クラス(クライアント)のインスタンスを作成しています。
終わりに
間違いあったら指摘おなしゃーす。