【学習メモ】Laravelのサービスコンテナについて調べたこと
Laravelにはサービスコンテナ、サービスプロバイダという仕組みがあります。
これらについて全くの無知だったため、調べました。
・サービスコンテナとは?
【Laravel】サービスコンテナとは?2つの強力な武器を持ったインスタンス化マシーン。簡単に解説。
上記のサイトによると、サービスコンテナとは
「クラスをインスタンス化してくれる便利な機能」のようです。
$ClassA = app()->make(ClassA::class);
のようにして使います。
こうすると変数$ClassA
にClassAのインスタンスが代入されます。
・では、何が便利なのか?
一つは「依存解決をしてくれる」こと
もう一つは「インスタンス化の方法を選べる」こと
のようです。
・依存解決をしてくれると何がいいのか?
ここにインスタンス化したいClassAがあるとします。このClassAはコンストラクタの中でClassBをインスタンス化して利用しているとします。するとClassAをインスタンス化するためには、まず最初にClassBをインスタンス化し、それを引数にしてClassAをインスタンス化しなければなりません。
サービスコンテナを使うと、ClassAをインスタンス化する際に、これ(ClassBのインスタンス化)を自動的にやってくれます。
流れとしては、
サービスコンテナ経由でClassAのインスタンス化を宣言
サービスコンテナがClassAを検査し、ClassAの内部でClassBが使われていることを発見
サービスコンテナがClassBをインスタンス化
インスタンス化したClassBを引き渡し、ClassAをインスタンス化
とイメージしました。
また、ClassBがさらにClassCをインスタンス化して使っていても、そのClassCがさらにClassDがインスタンス化して使っていたとしても、サービスコンテナは全てをインスタンス化して順繰りに渡していき、最終的なClassAのインスタンス化を終了させてくれます。
・インスタンス化の方法を選べるとはどういうことか?
ClassEをインスタンス化する際に、ClassEが持つプロパティ$hogeに文字列'hogehoge'を代入したいとします。
class ClassE
{
public $hoge;
public function __construct()
{
}
}
$app->bind
という機能を使うことでそれができます。
$app->bind
は、第一引数に「インスタンス化方法をカスタマイズしたいクラス」を、第二引数に「インスタンス化方法」を記述します。
例えば、
app()->bind(ClassE::class, function () {
$classE = new ClassE();
$classE->hoge = 'hogehoge';
return $classE;
});
とした場合、
$ClassE = $app()->make(ClassE::class);
を実行すると、サービスコンテナは
$classE = new ClassE();
$classE->hoge = 'hogehoge';
を実行した後で、
return $classE;
によってClassEのインスタンスを返します。
ClassEに依存解決をする必要があるのならば、
app()->bind(ClassE::class, function ($app) {
- $classE = new ClassE();
+ $classE = $app()->make(ClassE::class);
$classE->hoge = 'hogehoge';
return $classE;
});
と、bind内で$app()->make()
を使います。
app()->bind(ClassE::class, function ($app) {
$classX = $app()->make(ClassX::class);
return $classX;
});
と記述すれば、$app()->make(ClassE::class);
の返り値はClassXのインスタンスになります。
このbindによるインスタンス化方法の記述を「結合」と言います。
Discussion