Laravel のサービスコンテナでは、DI の手法として、コンストラクタインジェクションとメソッドインジェクションをサポートしています。サービスコンテナの機能を応用することで、セッターインジェクションを利用できます。
このエントリは、Laravelリファレンス Advent Calendar 2015 の11日目です。
セッターインジェクション
DI する対象クラスが、以下の MessageDeliveryクラスです。このクラスは、Sender を必要としているので、setSender メソッドで与えます。この setSender メソッドで依存インスタンスを与えるのが、セッターインジェクションです。
サービスコンテナを利用することで、このクラスをコンテナで解決すると、自動で setSender メソッドが実行され、Sender を実装したインスタンスを与えることができます。
class MessageDelivery { /** * @var Sender */ protected $sender; public function send($to, $message) { $this->sender->send($to, $message); } public function setSender(Sender $sender) { $this->sender = $sender; } }
サービスコンテナによるセッターインジェクション
サービスコンテナでセッターインジェクションを行うには、extend メソッドを利用します。これは、サービスコンテナにて解決を行った直後に自動で呼ばれる処理を登録するメソッドです。
この処理では、引数に解決されたインスタンスとサービスコンテナのインスタンスが渡されます。そこで、解決されたインスタンスのセッターメソッドを呼ぶことで必要なインスタンスを与えます。
下記が、その例です。ここでは、MessageDelivery::class を解決した際に実行する処理をクロージャで指定しています。クロージャでは、setSender メソッドで、Sender インターフェイスを実装した MailSender クラスのインスタンスを渡しています。
app()->extend(MessageDelivery::class, function ($instance, $app) { $instance->setSender(app()->make(MailSender::class)); return $instance; }); $delivery = app()->make(MessageDeliverySetterInjection::class); $delivery->send('to', 'message');
さいごに
サービスコンテナによるセッターインジェクションを見てみました。extend メソッドは、セッターインジェクションのためだけのものではないので、解決に付随した処理(初期化等)があれば活用すると良いでしょう。
DI やコンストラクタインジェクション、メソッドインジェクションについては、下記をどうぞ :)
Laravel リファレンス[Ver.5.1 LTS 対応] Web職人好みの新世代PHPフレームワーク
- 作者: 新原雅司,竹澤有貴,川瀬裕久,大村創太郎,松尾大
- 出版社/メーカー: インプレス
- 発売日: 2016/01/08
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る