LoginSignup
0
0

Laravel学習メモ:サービスコンテナ

Posted at

サービスコンテナ 10.x Laravel

  • Laravelサービスコンテナはクラスの依存関係の管理と注入を実行するための機能

  • コンストラクタまたは場合によってはセッターメソッドを介してクラスに「注入」される。

  • クラスに依存関係がない場合か他の具象クラスのみに依存している場合は依存解決の方法をコンテナに指示する必要はない。

    <?php
    
    class Service
    {
        // ...
    }
    
    Route::get('/', function (Service $service) {
        die($service::class);
    });
    
  • コンテナを使うタイミング

    • ルート定義で依存関係に注入可能(バックグラウンドで管理されている状況)
    • 手作業でコンテナ操作をするのは…
      • クラスコンストラクタ
        • コンテナにそのインターフェイスを解決する方法を指示する
        • パッケージのサービスをコンテナに結合する必要あり
  • 結合の基本

    • サービスプロバイダ内では常に$this→appプロパティを使用してコンテナにアクセスできる。

      • bindメソッドを使用して結合を登録できる。
      • 登録するクラスまたはインターフェイス名をクラスのイインスタンスを返すクロージャとともに渡す
      use App\Services\Transistor;
      use App\Services\PodcastParser;
      use Illuminate\Contracts\Foundation\Application;
      
      $this->app->bind(Transistor::class, function (Application $app) {
          return new Transistor($app->make(PodcastParser::class));
      });
      
      • リゾルバの引数としてコンテナ自体を受け取ることに注意する。
    • 通常はサービスプロバイダ内のコンテナの中で操作するが、外部でコンテナとやり取りがしたい

      • Appファサードを使用して操作する。
      use App\Services\Transistor;
      use Illuminate\Contracts\Foundation\Application;
      use Illuminate\Support\Facades\App;
      
      App::bind(Transistor::class, function (Application $app) {
          // ...
      });
      
      • bindIfメソッドを利用すれば指定するタイプに対する結合がまだ登録されていない場合にのみ登録できる。
    • Note:

      • クラスがどのインターフェイスにも依存しない場合、クラスをコンテナに結合する必要はありません。
  • シングルトンの結合

    • singletonメソッドはクラスまたはインターフェイスを1回のみコンテナに結合する
  • コンテキストによる結合

    • 同じインターフェイスを利用する2つのクラスがある場合、各クラスに異なる実装を依存注入したい場合がある。
    use App\Http\Controllers\PhotoController;
    use App\Http\Controllers\UploadController;
    use App\Http\Controllers\VideoController;
    use Illuminate\Contracts\Filesystem\Filesystem;
    use Illuminate\Support\Facades\Storage;
    
    $this->app->when(PhotoController::class)
              ->needs(Filesystem::class)
              ->give(function () {
                  return Storage::disk('local');
              });
    
    $this->app->when([VideoController::class, UploadController::class])
              ->needs(Filesystem::class)
              ->give(function () {
                  return Storage::disk('s3');
              });
    
  • 依存解決

    • makeメソッド

      • コンテナからクラスインスタンスを解決する。
      use App\Services\Transistor;
      
      $transistor = $this->app->make(Transistor::class);
      
      • クラスの依存関係の一部がコンテナを介して解決できない場合はmakeWithメソッドに渡すことで依存注入できる
      • サービスプロバイダの外部で、$app変数にアクセスできないコードの場所では、Appファサードappヘルパを使用してコンテナからクラスインスタンスを依存解決します。
      use App\Services\Transistor;
      use Illuminate\Support\Facades\App;
      
      $transistor = App::make(Transistor::class);
      $transistor = app(Transistor::class);
      
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0