Laravel における依存関係注入の実装原理は、クラスメソッドのリフレクションを使用してパラメータの型を取得し、次にコンテナを使用してインスタンスを構築し、コールバック関数を使用してそれを呼び出すことです (注入されたオブジェクト)コンストラクターにはパラメーターを含めることはできません。そうでない場合は、エラーが報告されます。依存関係の注入は Router クラスによって開始する必要があります。そうでない場合、新しいメソッドを使用して注入を直接行うことはできません。
#この記事の動作環境: Windows 10 システム、Laravel バージョン 6、Dell G3 コンピューター。
laravel コンテナには制御の反転と依存関係注入が含まれています。これを使用するには、最初にオブジェクトをバインドする必要があり、直接使用できます。必要なときに取得できるようにします。
具体的な分析については、http://laravelacademy.org/post/769.html
通常の通話は次のとおりです。
$config = $container->make('config'); $connection = new Connection($this->config);
これは理解しやすいです。この利点は、インスタンスを直接新規作成する必要がないことです。メソッドによって渡される値は変更されません。このインスタンスを複数の場所で共有することもできます。
しかし、これは依存関係の注入と何の関係があるのでしょうか?実際の依存関係の注入では、メソッドにパラメーター値を渡す必要はありません。メソッドのパラメーターの型を指定するだけでよく、コードは自動的に関係を作成し、依存関係を自動的に挿入します。
この機能は、次のように Laravel のコントローラー、ジョブなどに反映できます:
class TestController extends Controller { public function anyConsole(Request $request, Auth $input) { //todo } }
自動依存関係注入がどのように実装されるかを見てみましょう:
インデックスによる. PHP はカーネルを呼び出し、多層のカーネル パイプラインを介して呼び出し、次に多層のミドルウェア パイプラインを介してルーターを呼び出します。最後に、
Illuminate/Routing/Route.php の 124 行目にあります。
public function run(Request $request) { $this->container = $this->container ?: new Container; try { if (! is_string($this->action['uses'])) { return $this->runCallable($request); } if ($this->customDispatcherIsBound()) { return $this->runWithCustomDispatcher($request); } return $this->runController($request); } catch (HttpResponseException $e) { return $e->getResponse(); } }
$this->action['uses'] (\App\Http\Controller\Datacenter\RealTimeController@anyConsole などの形式行) が文字列かどうかを判断します。$this->customDispatcherIsBound が判断します。バインドされているかどうか ユーザー定義のルーティングが定義されています。次に、$this->runController($request) にジャンプします。
protected function runController(Request $request) { list($class, $method) = explode('@', $this->action['uses']); $parameters = $this->resolveClassMethodDependencies( $this->parametersWithoutNulls(), $class, $method ); if (! method_exists($instance = $this->container->make($class), $method)) { throw new NotFoundHttpException; } return call_user_func_array([$instance, $method], $parameters); }
$this->resolveClassMethodDependities このメソッドは、名前を見るとすぐに探しているメソッドです。 $this->parametersWithoutNulls() は null 文字を除外するためのものです。$class と $method はそれぞれ \App\Http\Controller\Datacenter\RealTimeController と anyConsole です。
protected function resolveClassMethodDependencies(array $parameters, $instance, $method) { if (! method_exists($instance, $method)) { return $parameters; } return $this->resolveMethodDependencies( $parameters, new ReflectionMethod($instance, $method) ); }
new ReflectionMethod($instance, $method) は、クラス メソッドを取得するリフレクション オブジェクトです。ドキュメントを参照してください: http://www.php.net/manual/zh/class.reflectionmethod.php
以下は、Illuminate/Routing/RouteDependencyResolverTrait.php の 54 行目にジャンプします。
public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector) { $originalParameters = $parameters; foreach ($reflector->getParameters() as $key => $parameter) { $instance = $this->transformDependency( $parameter, $parameters, $originalParameters ); if (! is_null($instance)) { $this->spliceIntoParameters($parameters, $key, $instance); } } return $parameters; }
リフレクション クラス メソッドを通じてクラス パラメーター配列を取得し、それをトラバースして $this->transformDependency メソッドに渡します。インスタンスを取得できない場合は、$this->spliceIntoParameters を呼び出してパラメータをクリアします。
protected function transformDependency(ReflectionParameter $parameter, $parameters, $originalParameters) { $class = $parameter->getClass(); if ($class && ! $this->alreadyInParameters($class->name, $parameters)) { return $this->container->make($class->name); } }
ようやくコンテナの影が見えました、はい、コンテナのmakeメソッドで最終オブジェクトを取り出しました。この時点でパラメータが構築され、最終的には runController メソッドの call_user_func_array によってコールバックされます。
概要:
依存関係注入の原理は、実際にはクラス メソッドのリフレクションを使用してパラメーターの型を取得し、コンテナーを使用してインスタンスを構築することです。次に、コールバック関数を使用して呼び出します。
注入オブジェクト コンストラクターにはパラメーターを含めることはできません。それ以外の場合は、エラーが報告されます。引数 1
がありません。依存関係の注入は有効ですが、Router クラスによって呼び出される必要があります。そうしないと、新しいメソッドを使用して直接注入を行うことができません。これが、コントローラー クラスとジョブ クラスのみがこの機能を使用できる理由です。
[関連する推奨事項: laravel ビデオチュートリアル ]
以上がLaravelにおける依存性注入の実装原理は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。