モジュール
モジュールは、DIとAOPの束縛のセットです。BEAR.Sundayでは、一般的な設定ファイルやConfigクラス、実行モードなどは存在しません。各コンポーネントが必要とする値は、依存性の注入により提供されます。モジュールがこの依存性の束縛を担当します。
アプリケーションの起点となるモジュールはAppModule(src/Module/AppModule.php)です。
AppModule内で、他の必要なモジュールをinstallします。
モジュールが必要とする値(ランタイムではなく、コンパイルタイムで必要な値)は、手動のコンストラクタインジェクションにより束縛を行います。
class AppModule extends AbstractAppModule
{
/**
* {@inheritdoc}
*/
protected function configure()
{
// 追加モジュール
$this->install(new AuraSqlModule('mysql:host=localhost;dbname=test', getenv('db_username'), getenv('db_password')));
$this->install(new TwigModule());
// package標準のモジュール
$this->install(new PackageModule());
}
}
DIの束縛
以下に代表的な束縛パターンを示します:
// クラスの束縛
$this->bind($interface)->to($class);
// プロバイダー(ファクトリー)の束縛
$this->bind($interface)->toProvider($provider);
// インスタンス束縛
$this->bind($interface)->toInstance($instance);
// 名前付き束縛
$this->bind($interface)->annotatedWith($annotation)->to($class);
// シングルトン
$this->bind($interface)->to($class)->in(Scope::SINGLETON);
// コンストラクタ束縛
$this->bind($interface)->toConstructor($class, $named);
詳細についてはDIをご参照ください。
AOPの設定
AOPは、クラスとメソッドをMatcherで”検索”し、マッチするメソッドにインターセプターを束縛します。
// 例1:メソッド名による束縛
$this->bindInterceptor(
$this->matcher->any(), // どのクラスの
$this->matcher->startsWith('delete'), // "delete"で始まるメソッド名のメソッドには
[Logger::class] // Loggerインターセプターを束縛
);
// 例2:クラスとアノテーションによる束縛
$this->bindInterceptor(
$this->matcher->SubclassesOf(AdminPage::class), // AdminPageの継承または実装クラスの
$this->matcher->annotatedWith(Auth::class), // @Authアノテーションがアノテートされているメソッドには
[AdminAuthentication::class] // AdminAuthenticationインターセプターを束縛
);
詳細についてはAOPをご参照ください。
束縛の優先順位
参照: Ray.Di 束縛
同一モジュール内での優先順位
同じモジュール内では、先に束縛された方が優先されます。以下の例では、Foo1が優先されます:
$this->bind(FooInterface::class)->to(Foo1::class);
$this->bind(FooInterface::class)->to(Foo2::class);
モジュールインストールでの優先順位
先にインストールされたモジュールが優先されます。以下の例では、Foo1Moduleが優先されます:
$this->install(new Foo1Module);
$this->install(new Foo2Module);
後からのモジュールを優先させたい場合は、overrideを使用します。以下の例では、Foo2Moduleが優先されます:
$this->install(new Foo1Module);
$this->override(new Foo2Module);
コンテキスト文字列での優先順位
コンテキストモジュールは逆順(右から左)で処理されます。例えば、prod-hal-api-appの場合:
インストール順序: AppModule → ApiModule → HalModule → ProdModule
後からインストールされたモジュールが先のモジュールの束縛を上書きできます。つまり:
HalModuleはAppModuleより優先ProdModuleはHalModuleより優先
組み込みコンテキスト(HalModuleなど)の束縛を上書きするカスタムコンテキストモジュールを作成する場合、コンテキスト文字列でそのコンテキストの左側に配置します。例えば、HalModuleのRenderInterface束縛を上書きするには:
// コンテキスト: "prod-mycontext-hal-api-app"
// インストール順序: AppModule → ApiModule → HalModule → MycontextModule → ProdModule