こんにちは。ファガイです。
本日は、Laravel5のContainerクラスに存在するメンバ変数に関して調べました。
resolved
すでに解決済みの依存関係情報を登録しています。Containerでmakeされるまではresolvedには情報は入りません。
基本的に、'binding名' => true
で入ります。
bindings
すでにコンテナにバインディングされているかの情報が入っています。
中身は’binding名’ => [‘concrete’ => ‘binding先'(, ‘shared’ => true)]
$this->app->bind('FooInterface', 'Bar');
→'FooInterface' => ['concreate' => Closure]
$this->app->singleton('FooInterface', 'Bar');
$this->app->bindShared('FooInterface', function($app) {
return new Bar;
});
→'FooInterface' => ['concreate' => Closure, 'shared' => true]
instances
共有インスタンス化されている物が配列で入っています。
makeメソッドが呼ばれた際、そのbindingsのsharedがtrueだった場合や、instanceメソッドでインスタンスを登録する場合にこのinstancesに登録されます。
中身は、'binding名' => インスタンスそのもの
です。
aliases
2015/05/06 内部仕様を勘違いしていたので修正しました。
別名を登録する際に使われています。主に使用されるのはコンストラクタインジェクション等を使えるようにするために使われてます。
中身は、'alias名' => 'binding名'
です。
Applicationクラスの最後の方に、aliasの登録が存在するので見ると良いです。
extenders
bindingされている物に対して、makeされる際に追加で何か実行させたい等があるときにはこれが使われています。
extendメソッドでextendersに登録しています。
中身は'binding名' => [Closure,Closure・・・]
です。
tags
タグに対応したbindingされている物が格納されています。
登録には、tagメソッド、取得にはtaggedメソッドを使います。また、taggedで返されるのは、tagに紐付いているbindingをmakeした物が配列で返されます。
buildStack
自身で読み解いていった結果、コンテキストバインディングを使用するときだけこのbuildStackが使われているようです。現状ではコンテキストバインディングにしか使われていないようなので、あまり気にしないほうがいいのと、そもそもメンバ変数でこれを持つべきなのかと微妙な感じです。
build→データを入れる→getDependencies→resolveClass→make→getConcrete→getContextualConcreteでデータを使用している→buildまで戻ってきたらデータをpopして出す
contextual
コンテキストバインディングの情報が入ります。
Containerクラスのwhenメソッドが呼ばれるとContextualBindingBuilderクラスがnewされ、最終的にgiveメソッドが呼ばれるとContainerクラスのaddContextualBindingメソッドを通じてこの配列に登録されます。
$this->contextual[whenメソッドの第1引数][needsメソッドの第1引数] = giveメソッドの第1引数
コンテキストに合わせた結合 – サービスコンテナ 5.0.0 Laravel
reboundCallbacks
resolve済みのbindingが再度インスタンスが登録(rebound)される際に呼ばれるコールバック関数がこの中に入ります。
追加する際には、rebindingメソッドを使います。
vendor/laravel/framework/src/Illuminate/Routing/RoutingServiceProvider
などで実際に使われてます。
Resolving系
いきなり見出しをつけてしまいましたが、resolving関係はメンバ変数が複数存在し、実際登録する際のコールバックが一緒だったのでまとめています。
Resolving関係は、依存関係が解決された際(make)に毎回呼ばれます。(singleton等は基本的に最初の1回だけです。)
また、Resolvingはextenderよりも後に発火します。
コンテナイベント – サービスコンテナ 5.0.0 Laravel
make時に発火される順番
resolvingのイベントは複数指定が可能なので、発火される順番が存在します。以下となります。
- globalResolvingCallbacks
- resolvingCallbacks
- globalAfterResolvingCallbacks
- afterResolvingCallbacks
resolving登録時のコールバック
$callback(生成されたオブジェクト, Applicationコンテナ)
上記のように渡されます。
globalResolvingCallbacks
resolvingメソッド→resolvingCallbackメソッドで登録されます。クロージャの第1引数でクラス指定をしなければこちらに登録されます。
全ての依存関係が解決される際に毎回呼ばれます。
$this->app->resolving(function($object, $app)
{
// どんなものでもmakeされれば実行されます
});
resolvingCallbacks
resolvingメソッドまたは、resolvingCallbackメソッドで登録されます。resolvingCallbackメソッドでは、クロージャの第1引数でクラス指定をするとこちらに登録されます。
依存解決の名前が第1引数で指定したものに対応した名前でないと、このコールバックは動作しません。
$this->app->resolving(function(FooBar $fooBar, $app)
{
// FooBarでbindingされているまたは、FooBarクラスだったら実行されます
});
$this->app->resolving('FooBar', function($fooBar, $app)
{
// これでも同じです
});
globalAfterResolvingCallbacks
afterResolvingメソッド→afterResolvingCallbackメソッドで登録されます。クロージャの第1引数でクラス指定をしなければこちらに登録されます。
その他情報はglobalAfterResolvingCallbacksと同じです。
afterResolvingCallbacks
afterResolvingメソッドまたは、afterResolvingCallbackメソッドで登録されます。afterResolvingCallbackメソッドでは、クロージャの第1引数でクラス指定をするとこちらに登録されます。
その他情報はresolvingCallbacksと同じです。
まとめ
まだまだ理解できてない曖昧な部分が有りますがある程度理解できて良かったです。
resolvingやextenderに関しては新鮮でしたー。
コメント