Export to GitHub

bearsunday - module.wiki


導入

モジュールはDIとAOPの束縛(バインド)の設定の集合です。オブジェクトの抽象、つまりインターフェイスや抽象クラスと実装、実クラスやファクトリーの束縛、それにメソッドとその横断的振る舞い、つまりアスペクトの束縛の集合です。DIの設定ではインターフェイスに対してクラスを束縛します。AOPは特定のメソッドに対してインターセプターを束縛します。

モジュールはこの束縛の集合によってオブジェクトがどのように組み立てられ利用されるかを決定します。インジェクターはそのモジュールを利用してオブジェクトの生成を行います。そのオブジェクトのメソッドの利用には束縛されたインターセプターが機能します。

例えばAPIモジュールでは出力インターフェイスにJSON出力のクラスが束縛されているので出力がJSONになります。出力オブジェクトがモードに応じて振る舞いを*変えているのではない事*に注目してください。モードに応じて振る舞いを帰るのではなく、モードに応じてオブジェクトの構成を変更しています。

BEAR.Sundayは変更に対して開いていて修正に対して閉じているオブジェクトの開放閉鎖原則(OCP)に従っています。

束縛DSL

モジュールはAbstractModuleを継承し、configureメソッド内ではバインドDSLをDSLを使い@Injectでアノテートされたインジェクションポイントにどのようにインスタンス提供するかを束縛します。

バインドの種類

AbstractModuleを継承したモジュールのconfigureメソッド内で、@Injectでアノテートされたインジェクションポイントにどのようにインスタンス提供をするかを束縛します。インスタンスの提供は様々な方法があり、引き数なしのクラス名を指定するLinked Binding、名前を使って束縛する"Named" Binding、プロバイダーといわれる専用のファクトリーを使って束縛するProvider Bindings等があります。

束縛 (binding)

Linked Binding

インターフェイス名と実クラス名を束縛します。

$this->bind('TransactionLog')->to('DatabaseTransactionLog');

最も単純で一般的な方法です。コンストラクタに引数を渡す事は出来ない事に注意してください。これは以下のように@Injectで指定されたTransactionLogインターフェイスにnew DatabaseTransactionLog();で生成したインスタンスをインジェクトします

コンシュマー(インジェクトされる側) /** * @Inject */ public function setLog(TransactionLog $log)

"Named" Binding

バインドに名前をつけます。

$this->bind('CreditCardProcessor')->annotatedWith('Checkout')->to('CheckoutCreditCardProcessor'); コンシュマー

/** * @Inject * @Named("serceret_key") */ public function setProcessor(CreditCardProcessor $processor)

インターフェイスがないscalar型への束縛には@Namedで指定する名前が必須です。

$this->bind()->annotatedWith('secret_key')->toInstance(1234);

コンシュマー /** * @Inject * @Named("serceret_key") */ public function setKey($stringKey)

Instance Bindings

インスタンス(実体)をバインドします。これはnewキーワードで作成されたクラスのインスタンスに限りません。数値や文字列も含みます。インスタンスバインディングは他のバインディグ方法が利用可能なら、なるべく避けるべきバインディングです。他のbind()と違って実際に使用されないインスタンスも作成されてしまいます。

$this->bind()->annotatedWith("login_timeout_seconds")->toInstance(10);

Provider Bindings

オブジェクトのコンストラクションに引数が必要なものや、オブジェクトのコンストラクションが複雑なものはプロバイダーというファクトリークラスをバインドします。プロバイダーはproviderインターフェイスを実装したgetメソッドがインスタンスを返します。

``` $this->bind('TransactionLog')->toProvider('DatabaseTransactionLogProvider');

```

※TransactionLogインターフェイスはDatabaseTransactionLogProvidergetプロバイダーにバインドされます。このインジェクトが行われるタイミングでgetメソッドがコールされインスタンスが取得されます。

Constructor Bindings

コンストラクターバインディングは、3rd partyのクラス(BEAR.Sunday、そのアプリケーション以外)、つまり@Injectでインジェクションポイントがマークされてないクラスのインジェクションを行うための束縛です。

コンストラクターの変数名をインジェクションポイントとして指定して束縛ドします。

$this->bind('TransactionLog')->toConstructor(['db' => new Database]);

Scope

オブジェクトを*Singleton**として指定するために2つの方法があります。1つはクラスにアノテーションで指定する方法、もう一つはバインドの時に指定する方法です。**

/** * @Scope(Scope::SINGLETON) */ public class InMemoryTransactionLog implements TransactionLog { }

$this->bind('TransactionLog')->to('InMemoryTransactionLog')->in(Scope::Singleton);

Ray.DI

BEAR.Sundayが利用しているDIフレームワーク、Ray.Di Ray.Diのマニュアルもご覧下さい。