bitrix-service-locator について
Bitrix Framework の依存性注入を扱う開発者向け ServiceLocator スキルです。サービスの解決、登録、上書き方法と、コンストラクター注入の適用箇所を説明します。
主な機能
- 01サービス解決と自動注入のルール
- 02設定ファイルでのサービス登録
- 03グローバルおよび実行時の上書き
- 04コンポーネント別の注入方法
- 05ライフサイクルとドメイン層の規則
活用シーン
- 01インターフェース実装の登録
- 02サービス内での依存関係の解決
- 03モジュールのバインドの上書き
- 04コマンド内でのコンテナー利用
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bxmaximum/ bitrix-framework-skills --skill bitrix-service-locatorインストール後、Claude Code で/bitrix-service-locatorを入力して読み込まれたか確認します。
詳細
ServiceLocator(DI)
ベースライン:main 23.0 以降 · 検証済み:main 26.800.0
コンストラクター DI が許可される場所(サービスは可、コントローラーはアクションパラメーター経由、コマンドとハンドラーは不可):bitrix-framework。ドメインクラスからコンテナーにアクセスすることはありません。
get($id) の解決方法(main 26.250* 以降)
| キー | 結果 |
|---|---|
すでに構築済み、または addInstance() で登録済み | 同じインスタンス |
| 未登録で、クラスが存在する | オートワイヤリング:各コンストラクターパラメーターに対して get(<its type>) を実行します。デフォルト値があるパラメーターにはその値を使用します |
| 登録済みのインターフェイス/抽象クラス | className → 実装をオートワイヤリングします(constructorParams は無視されます)。constructor クロージャー → constructorParams を引数として呼び出します |
| 登録済みの具象クラスまたは文字列 ID | className → new $class(...array_values(constructorParams))(オートワイヤリングなし)。constructor クロージャー → 引数なしで呼び出します |
- エントリーに
'singleton' => falseが設定されていない限り、インスタンスはプロセス内でキャッシュされます。 - 循環依存があると
CircularDependencyExceptionがスローされます。型指定のないパラメーター、ユニオン型のパラメーター、またはデフォルト値のないスカラー型のパラメーターがあるとServiceNotFoundExceptionがスローされます。 - 26.250 より前:登録済みのキーはすべて
new $class(...constructorParams)またはconstructor()で構築されます。未登録のクラスは、すべてのコンストラクターパラメーターが具象クラスの場合に限りオートワイヤリングされます(インターフェイスは不可。デフォルト値は無視されます)。singletonオプションはありません。このようなカーネルでは、依存関係のある実装をconstructorクロージャーでバインドします。
登録
Loader::includeModule() 時に登録される /local/modules/vendor.module/.settings.php の services、またはグローバル設定:
<?php
return [
'services' => [
'value' => [
// interface → implementation (autowired since 26.250*)
\Vendor\Blog\Domain\PostRepositoryInterface::class => [
'className' => \Vendor\Blog\Infrastructure\OrmPostRepository::class,
],
// scalar arguments → factory
\Vendor\Blog\Infrastructure\TelegramClient::class => [
'constructor' => static fn () => new \Vendor\Blog\Infrastructure\TelegramClient(
(string)getenv('TELEGRAM_BOT_TOKEN'),
),
],
// positional args; closure evaluated on first get()
'vendor.blog.mailer' => [
'className' => \Vendor\Blog\Infrastructure\Mailer::class,
'constructorParams' => static fn () => ['[email protected]'],
],
],
'readonly' => true,
],
];
- 他のクラスだけを必要とする具象クラスは登録しないでください。
get(PostService::class)はオートワイヤリングしますが、[ 'className' => PostService::class ]だけを指定するとnew PostService()が実行され、ArgumentCountErrorが発生します。 - FQCN キーを優先してください。文字列 ID(
main.validation.service)はカーネルのスタイルです。 - カーネルは
Application、Routing\Router、DB\Connection、Data\Cache、Data\ManagedCache、Data\TaggedCache、EventManager、Data\ConnectionPool、\CUserTypeManager(main 26.250* 以降)、Data\Storage\PersistentStorageInterface(main 25.1100 以降、bitrix-storage)を登録します。Application::getInstance()->…を呼び出すのではなく、コンストラクターにインジェクションしてください。
オーバーライド
- 最初の登録が優先されます。
registerByModuleSettings()は、すでに存在するキーをスキップします。後から読み込まれたモジュールで、先に登録された内容をオーバーライドすることはできません。 - モジュールのバインドをオーバーライドするには、アプリケーションの起動時(モジュールより前)に登録される
/local/.settings_extra.phpのグローバルservices、または実行時(init.php、テスト)に設定します:ServiceLocator::getInstance()->addInstance($id, $object)/addInstanceLazy($id, ['className' => …])。
サービスの取得
- サービス:コンストラクターパラメーターを使用します。
- コントローラーのアクション:具象クラスを型指定します。アクションパラメーターのインターフェイスは解決されません(
bitrix-controllers)。 - Messenger のレシーバーは
get(FQCN)で構築されるため、オートワイヤリングされます。コンソールコマンドとイベントハンドラーはオートワイヤリングされないため、execute()/ハンドラー内でServiceLocator::getInstance()->get(Foo::class)を呼び出してください。 has($id)がtrueを返すのは、登録済みまたは構築済みの ID のみです。オートワイヤリング可能なクラスは対象外です。
ルール
- サービスはプロセスごとのシングルトンです。プロパティにリクエストごとの状態を保持しないでください。長時間実行されるコンシューマーは、メッセージ間でインスタンスを保持します。
- コンテナーで構築できる場合、コントローラー/コマンド内で
new Service()を使用しないでください。ドメインコードからコンテナーを呼び出さないでください。 - 設定は、型付きオブジェクトまたはファクトリー経由のスカラー値として渡し、生の配列をサービスとして渡さないでください。
- 機能フラグには、自作のフラグサービスではなく、カーネルの
Bitrix\Main\Config\Feature(main 26.700 以降、bitrix-storage)を使用してください。
コメント
Markdown 対応