目次
依存性注入
コンストラクター メソッドの挿入
セッター メソッドの挿入
インターフェイス注入
利点
制御の反転
Laravel Ioc
小贴士
ホームページ PHPフレームワーク Laravel laravel依存性注入とは何ですか

laravel依存性注入とは何ですか

Dec 22, 2021 am 11:32 AM
laravel 依存性注入

laravel 依存性注入という用語は、Martin Fowler によって提案された用語です。アプリケーションにコンポーネントを注入する動作です。依存性注入は、アジャイル アーキテクチャの重要な要素です。使用例は、「class UserProvider{保護された $connection...}"。

laravel依存性注入とは何ですか

この記事の動作環境:Windows 7 System、Laravelバージョン5.7、Dell G3コンピューター。

laravel 依存関係注入とは何ですか?

Laravel における依存関係注入と IoC の詳細な説明:

開発者として、私たちはデザイン パターンを使用したり、新しい堅牢なフレームワークを試したりすることで、適切に設計された堅牢なコードを作成する新しい方法を常に見つけようとしています。この記事では、Laravel の IoC コンポーネントを使用した依存性注入の設計パターンを調査し、それがどのように設計を改善できるかを見ていきます。

依存性注入

依存性注入という用語は、Martin Fowler によって提案された用語であり、アプリケーションにコンポーネントを注入する行為です。 Ward Cunningham 氏は次のように述べています:

依存性注入はアジャイル アーキテクチャの重要な要素です。

例を見てみましょう:

class UserProvider{
    protected $connection;

    public function __construct(){
        $this->connection = new Connection;
    }

    public function retrieveByCredentials( array $credentials ){
        $user = $this->connection
                        ->where( 'email', $credentials['email'])
                        ->where( 'password', $credentials['password'])
                        ->first();

        return $user;
    }
}
ログイン後にコピー

このクラスをテストまたは保守したい場合は、データベース インスタンスにアクセスしていくつかのクエリを実行する必要があります。これを回避するには、このクラスを他のクラスから 分離 することができます。Connection クラスを直接使用せずに挿入する 3 つのオプションのいずれかがあります。

コンポーネントをクラスに挿入するときは、次の 3 つのオプションのいずれかを使用できます。

コンストラクター メソッドの挿入

class UserProvider{
    protected $connection;

    public function __construct( Connection $con ){
        $this->connection = $con;
    }
    ...
ログイン後にコピー

セッター メソッドの挿入

同様に、 Setter メソッドを使用して依存関係を注入することもできます。

class UserProvider{
    protected $connection;
    public function __construct(){
        ...
    }

    public function setConnection( Connection $con ){
        $this->connection = $con;
    }
    ...
ログイン後にコピー

インターフェイス注入

interface ConnectionInjector{
    public function injectConnection( Connection $con );
}

class UserProvider implements ConnectionInjector{
    protected $connection;

    public function __construct(){
        ...
    }

    public function injectConnection( Connection $con ){
        $this->connection = $con;
    }
}
ログイン後にコピー

クラスがインターフェイスを実装するとき、依存関係を解決するために injectConnection メソッドを定義します。

利点

クラスをテストするときに、依存クラスをモックしてパラメーターとして渡すことができるようになりました。各クラスは特定のタスクに重点を置く必要があり、依存関係の解決には関心を持たないでください。こうすることで、より集中的で保守しやすいアプリケーションが作成されます。

DI についてさらに詳しく知りたい場合は、Alejandro Gervassio がこの連載記事で広範囲かつ専門的に取り上げていますので、必ずお読みください。では、IoCとは何でしょうか? IoC (制御の反転) では依存関係の注入を使用する必要はありませんが、依存関係を効果的に管理するのに役立ちます。

制御の反転

Ioc は、依存関係の解決を容易にする単純なコンポーネントです。オブジェクトをコンテナとして記述することができ、クラスが解決されるたびに依存関係が自動的に挿入されます。

Laravel Ioc

Laravel Ioc は、オブジェクトをリクエストするときに依存関係を解決する方法が少し特殊です:

laravel依存性注入とは何ですか

私たちは A を使用します。この記事では、簡単な例でそれを改善します。
SimpleAuth クラスは FileSessionStorage に依存するため、コードは次のようになります:

class FileSessionStorage{
  public function __construct(){
    session_start();
  }

  public function get( $key ){
    return $_SESSION[$key];
  }

  public function set( $key, $value ){
    $_SESSION[$key] = $value;
  }
}

class SimpleAuth{
  protected $session;

  public function __construct(){
    $this->session = new FileSessionStorage;
  }
}

//创建一个 SimpleAuth
$auth = new SimpleAuth();
ログイン後にコピー

これは古典的なアプローチです。コンストラクター Function の使用から始めましょう。注射が始まります。

class SimpleAuth{
  protected $session;

  public function __construct( FileSessionStorage $session ){
    $this->session = $session;
  }
}
ログイン後にコピー

次にオブジェクトを作成します:

$auth = new SimpleAuth( new FileSessionStorage() );
ログイン後にコピー

Laravel Ioc を使用してこれらすべてを管理したいと思います。

Application クラスは Container クラスを継承しているため、App ファサードを通じてコン​​テナにアクセスできます。

App::bind( 'FileSessionStorage', function(){
    return new FileSessionStorage;
});
ログイン後にコピー

bind メソッドの最初のパラメータはコンテナにバインドされる一意の ID で、2 番目のパラメータは FileSessionStorage## が実行されるたびに実行されるコールバック関数です。 # クラスが実行されますが、以下に示すようにクラス名を表す文字列を渡すこともできます。

注: Laravel パッケージを見ると、バインディングが ( viewview.finder## など) のようにグループ化されていることがわかります。 # ...)。 セッション ストアを MySQL ストレージに変換すると仮定すると、クラスは次のようになります。

class MysqlSessionStorage{

  public function __construct(){
    //...
  }

  public function get($key){
    // do something
  }

  public function set( $key, $value ){
    // do something
  }
}
ログイン後にコピー

依存関係を変更したので、

SimpleAuth

も変更する必要があります。関数を構築し、新しいオブジェクトをコンテナにバインドします。

高レベルのモジュールは低レベルのモジュールに依存すべきではなく、両方とも抽象オブジェクトに依存する必要があります。
抽象化は詳細に依存すべきではなく、詳細は抽象化に依存する必要があります。


Robert C. Martin

私たちの
SimpleAuth

クラスは、ストレージがどのように行われるかを気にする必要はなく、代わりにサービスの利用に重点を置く必要があります。 したがって、ストレージを抽象的に実装できます:

interface SessionStorage{
  public function get( $key );
  public function set( $key, $value );
}
ログイン後にコピー

これにより、

SessionStorage

インターフェイスのインスタンスを実装して要求できるようになります: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">class FileSessionStorage implements SessionStorage{   public function __construct(){     //...   }   public function get( $key ){     //...   }   public function set( $key, $value ){     //...   } } class MysqlSessionStorage implements SessionStorage{   public function __construct(){     //...   }   public function get( $key ){     //...   }   public function set( $key, $value ){     //...   } } class SimpleAuth{   protected $session;   public function __construct( SessionStorage $session ){     $this-&gt;session = $session;   } }</pre><div class="contentsignin">ログイン後にコピー</div></div> <p>如果我们使用 <code>App::make('SimpleAuth') 通过容器解析 SimpleAuth
类,容器将会抛出 BindingResolutionException ,尝试从绑定解析类之后,返回到反射方法并解析所有依赖项。

Uncaught exception 'Illuminate\Container\BindingResolutionException' with message 'Target [SessionStorage] is not instantiable.'
ログイン後にコピー

容器正试图将接口实例化。我们可以为该接口做一个具体的绑定。

App:bind( 'SessionStorage', 'MysqlSessionStorage' );
ログイン後にコピー

现在每次我们尝试从容器解析该接口时,我们会得到一个 MysqlSessionStorage 实例。如果我们想要切换我们的存储服务,我们只要变更一下这个绑定。

Note: 如果你想要查看一个类是否已经在容器中被绑定,你可以使用 App::bound('ClassName') ,或者可以使用 App::bindIf('ClassName') 来注册一个还未被注册过的绑定。

Laravel Ioc 也提供 App::singleton('ClassName', 'resolver') 来处理单例的绑定。
你也可以使用 App::instance('ClassName', 'instance') 来创建单例的绑定。
如果容器不能解析依赖项就会抛出 ReflectionException ,但是我们可以使用 App::resolvingAny(Closure) 方法以回调函数的形式来解析任何指定的类型。

Note: 如果你为某个类型已经注册了一个解析方式 resolvingAny 方法仍然会被调用,但它会直接返回 bind 方法的返回值。

小贴士

  • 这些绑定写在哪儿:
    如果只是一个小型应用你可以写在一个全局的起始文件 global/start.php 中,但如果项目变得越来越庞大就有必要使用 Service Provider 。

  • 测试:
    当需要快速简易的测试可以考虑使用 php artisan tinker ,它十分强大,且能帮你提升你的 Laravel 测试流程。

  • Reflection API:
    PHP 的 Reflection API 是非常强大的,如果你想要深入 Laravel Ioc 你需要熟悉 Reflection API ,可以先看下这个 教程 来获得更多的信息。

相关推荐:最新的五个Laravel视频教程

以上がlaravel依存性注入とは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Laravelで電子メールの送信が失敗したときに返品コードを取得する方法は? Laravelで電子メールの送信が失敗したときに返品コードを取得する方法は? Apr 01, 2025 pm 02:45 PM

Laravelの電子メールの送信が失敗したときに戻りコードを取得する方法。 Laravelを使用してアプリケーションを開発する場合、検証コードを送信する必要がある状況に遭遇することがよくあります。そして実際には...

DCAT管理者にデータを追加するためにクリックのカスタムテーブル関数を実装する方法は? DCAT管理者にデータを追加するためにクリックのカスタムテーブル関数を実装する方法は? Apr 01, 2025 am 07:09 AM

DCATを使用するときにDCATADMIN(Laravel-Admin)にデータを追加するためにカスタムクリックのテーブル関数を実装する方法...

PHPでの依存関係注射(DI)の概念を説明します。 PHPでの依存関係注射(DI)の概念を説明します。 Apr 05, 2025 am 12:07 AM

PHPで依存関係注入(DI)を使用することのコア値は、ゆるく結合されたシステムアーキテクチャの実装にあります。 DIは、依存関係を外部的に提供することにより、クラス間の直接的な依存関係を削減し、コードのテスト可能性と柔軟性を向上させます。 DIを使用する場合、コンストラクター、セットポイントメソッド、またはインターフェイスを介して依存関係を注入し、IOCコンテナと組み合わせてオブジェクトのライフサイクルと依存関係を管理できます。

Laravel Redis接続共有:選択方法が他の接続に影響するのはなぜですか? Laravel Redis接続共有:選択方法が他の接続に影響するのはなぜですか? Apr 01, 2025 am 07:45 AM

Laravel FrameworkでRedis接続の共有の影響とLaravelフレームワークとRedisを使用する際のメソッドを選択すると、開発者は問題に遭遇する可能性があります。

Laravel Multi-Tenant Extension Stancl/Tenancy:テナントデータベース接続のホストアドレスをカスタマイズする方法は? Laravel Multi-Tenant Extension Stancl/Tenancy:テナントデータベース接続のホストアドレスをカスタマイズする方法は? Apr 01, 2025 am 09:09 AM

Laravel Multi-Tenant拡張機能パッケージStancl/Tenancyのカスタムテナントデータベース接続Laravel Multi-Tenant ExtensionパッケージStancl/Tenancyを使用したマルチテナントアプリケーションを構築する際の...

バングラ部分モデル検索のlaravelEloquent orm) バングラ部分モデル検索のlaravelEloquent orm) Apr 08, 2025 pm 02:06 PM

LaravelEloquentモデルの検索:データベースデータを簡単に取得するEloquentormは、データベースを操作するための簡潔で理解しやすい方法を提供します。この記事では、さまざまな雄弁なモデル検索手法を詳細に紹介して、データベースからのデータを効率的に取得するのに役立ちます。 1.すべてのレコードを取得します。 ALL()メソッドを使用して、データベーステーブルですべてのレコードを取得します:useapp \ models \ post; $ post = post :: all();これにより、コレクションが返されます。 Foreach Loopまたはその他の収集方法を使用してデータにアクセスできます。

Laravel6プロジェクトでRedis接続の有効性を効果的に確認する方法は? Laravel6プロジェクトでRedis接続の有効性を効果的に確認する方法は? Apr 01, 2025 pm 02:00 PM

Laravel6プロジェクトでRedis接続の有効性を確認する方法は、特にプロジェクトがビジネス処理にRedisに依存している場合によく見られます。以下は...

Laravelデータベースの移行の遭遇重複クラス定義:複製の移行ファイルとクラス名の競合を複製する方法は? Laravelデータベースの移行の遭遇重複クラス定義:複製の移行ファイルとクラス名の競合を複製する方法は? Apr 01, 2025 pm 12:21 PM

Laravelデータベースの移行中にクラス定義を複製する問題が発生します。データベースの移行にLaravelフレームワークを使用する場合、開発者は「クラスが使用されています...

See all articles