ホームページ > バックエンド開発 > PHPチュートリアル > 独自の依存関係噴射コンテナを構築する方法

独自の依存関係噴射コンテナを構築する方法

Jennifer Aniston
リリース: 2025-02-15 13:22:12
オリジナル
619 人が閲覧しました

この記事では、単純な依存関係噴射コンテナ(DIコンテナ)PHPパッケージを構築する方法について説明します。 PHPDOCアノテーションや単体テスト(100%コードカバレッジ)を含む記事のすべてのコードは、GitHubリポジトリにアップロードされ、Packagistにリストされています。

How to Build Your Own Dependency Injection Container

キーポイント:

  • DIコンテナの構築は、開発者が依存噴射の基本原則とコンテナの作業メカニズムを理解するのに役立ちます。
  • diコンテナには、「依存噴射」と「コンテナ」という2つの主な機能があります。コンストラクターインジェクションまたはセッター噴射方法を使用して、インスタンス化してサービスを含める必要があります。
  • Symfony依存関係噴射コンテナは、カスタムコンテナを作成するための参照として使用できます。コンテナの構成をパラメーターとサービスに分割し、アプリケーションキーの安全なストレージを可能にします。
  • DIコンテナの作成には、プロジェクトディレクトリの作成、composer.jsonファイルの作成、コンテナの相互運用性インターフェイスの実装が含まれます。また、例外と参照クラスを作成することも含まれます。
  • コンテナクラスは、サービスを取得し、サービスが定義されているかどうかを確認する方法、パラメーターの解析、およびサービスの初期化のための方法を含める必要があります。また、円形の参照を防ぐための保護メカニズムも必要です。

依存関係噴射コンテナを計画します最初に、「依存関係噴射コンテナ」を「依存関係噴射」と「コンテナ」という2つの役割に分割します。

依存関係注入の最も一般的に使用される2つの方法は、コンストラクターインジェクションとセッターインジェクション、つまり、コンストラクターパラメーターまたはメソッド呼び出しを介してクラス依存関係を渡すことです。コンテナがインスタンス化してサービスを含めることができる場合、両方の操作を実行できる必要があります。

コンテナになるには、サービスのインスタンスを保存および取得できる必要があります。これは、サービスを作成するのに比べてかなり簡単な作業ですが、それでも検討する価値があります。

パッケージは、コンテナのセットが実装できるインターフェイスを提供します。メインインターフェイスは

です。これは、サービスが定義されているかどうかをテストするために、サービスを取得するための2つの方法です。 container-interop ContainerInterface

interface ContainerInterface
{
    public function get($id);
    public function has($id);
}
ログイン後にコピー
ログイン後にコピー
他の依存関係噴射コンテナを学習します

Symfony依存関係噴射コンテナを使用すると、さまざまな方法でサービスを定義できます。 YAMLでは、コンテナの構成が次のようになる場合があります:

Symfonyは、コンテナの構成をパラメーターとサービスに分割する方法に非常に役立ちます。これにより、APIキー、暗号化キー、認証トークンなどのアプリケーションキーが、ソースコードリポジトリから除外されたパラメーターファイルに保存されます。
parameters:
    # ...
    mailer.transport: sendmail

services:
    mailer:
        class:     Mailer
        arguments: ["%mailer.transport%"]
    newsletter_manager:
        class:     NewsletterManager
        calls:
            - [setMailer, ["@mailer"]]
ログイン後にコピー
ログイン後にコピー
PHPでは、Symfony依存関係インジェクションコンポーネントの同じ構成が次のとおりです。

オブジェクトを使用して、

へのメソッド呼び出しで、依存関係の注入ロジックは、この値を直接渡すべきではないことを検出できますが、コンテナ内のサービスIT参照に置き換える必要があります。これにより、混乱なくPHP値やその他のサービスをサービスに簡単に注入できます。
use Symfony\Component\DependencyInjection\Reference;

// ...
$container->setParameter('mailer.transport', 'sendmail');

$container
    ->register('mailer', 'Mailer')
    ->addArgument('%mailer.transport%');

$container
    ->register('newsletter_manager', 'NewsletterManager')
    ->addMethodCall('setMailer', array(new Reference('mailer')));
ログイン後にコピー

setMailerstartReference

最初に、新しいProjectディレクトリを作成し、Composerがクラスを自動的にロードするために使用できるファイルを作成します。現在、このファイルは、composer.json SitePointContainer src次に、コンテナをコンテナの相互運用性インターフェイスを実装するようにするため、作曲家にそれらをダウンロードして

ファイルに追加する必要があります:
interface ContainerInterface
{
    public function get($id);
    public function has($id);
}
ログイン後にコピー
ログイン後にコピー

composer.jsonメイン

に加えて、
parameters:
    # ...
    mailer.transport: sendmail

services:
    mailer:
        class:     Mailer
        arguments: ["%mailer.transport%"]
    newsletter_manager:
        class:     NewsletterManager
        calls:
            - [setMailer, ["@mailer"]]
ログイン後にコピー
ログイン後にコピー
パッケージは2つの例外インターフェイスも定義します。最初のものは、サービスを作成するときに遭遇する定期的な例外に使用され、要求されたサービスが見つからないときにもう1つが使用されます。また、要求されたパラメーターが見つからない場合、このリストに別の例外を追加します。

ContainerInterfacecontainer-interop(次のコンテンツでは、記事が長すぎてコアロジックが上記で説明されているため、コードの実装部分が省略されています。GitHubリポジトリの完全なコードには、例外クラス、参照クラス、およびコンテナの完全な実装が含まれています。クラス。)

概要

単純な依存関係噴射コンテナを作成する方法を学びましたが、まだ実装していない強力な機能を備えた他の多くのコンテナがあります!

PHP-DiやAura.diなどの一部の依存関係噴射コンテナは、Auto-Assemblyと呼ばれる機能を提供します。ここでは、コンテナがコンテナ内のどのサービスを他のサービスに注入する必要があるかを推測します。これを行うには、反射APIを使用してコンストラクターパラメーターに関する情報を見つけます。

好きなようにリポジトリを導き出し、自動アセンブリのような機能を追加できます。これは素晴らしい演習です!さらに、このコンテナのすべての既知のデリバティブバージョンの公開リストを保持して、他の人があなたがしていることを見ることができるようにします。以下のコメントを使用して作業を共有するだけで、必ず追加してください。

以下のコメントを使用してお問い合わせください。明確にしたり説明したりしたいもの、または見つけたエラーを教えてください。

(コンテンツが上記から非常に複製され、長すぎるため、FAQSセクションは省略されています。)

以上が独自の依存関係噴射コンテナを構築する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート