Laravelにおける依存性注入の実装原理は何ですか?

WBOY
リリース: 2022-02-18 11:06:44
オリジナル
6120 人が閲覧しました

Laravel における依存関係注入の実装原理は、クラスメソッドのリフレクションを使用してパラメータの型を取得し、次にコンテナを使用してインスタンスを構築し、コールバック関数を使用してそれを呼び出すことです (注入されたオブジェクト)コンストラクターにはパラメーターを含めることはできません。そうでない場合は、エラーが報告されます。依存関係の注入は Router クラスによって開始する必要があります。そうでない場合、新しいメソッドを使用して注入を直接行うことはできません。

Laravelにおける依存性注入の実装原理は何ですか?

#この記事の動作環境: Windows 10 システム、Laravel バージョン 6、Dell G3 コンピューター。

Laravel の依存関係注入の実装原理は何ですか?

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 サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!