Closed MikuroXina closed 9 months ago
/packages/bot/src/service/command.ts の registerAllCommandResponder は依存関係の注入処理をまとめているが, 明らかに依存関係と引数のサイズが肥大化しており管理が難しい. このまま今後の機能追加や改善は難しいのでこれを改善しつつ, 概念的に共通する依存関係の整理と直感的なサービス実装も維持できるようにしたい.
/packages/bot/src/service/command.ts
registerAllCommandResponder
まず, ドライバ層として /packages/bot/src/driver/ フォルダを追加する. そしてその配下に dep-registry.ts ファイルを追加し, 自前の DI コンテナ実装として依存関係レジストリを表す実装を追加する.
/packages/bot/src/driver/
dep-registry.ts
特定のシンボルに対応した抽象の型を定義するために, 次の型情報を export する. これは後述の Symbol の追加と interface のマージ処理を利用したテクニックである.
export
Symbol
interface
export type Dep0 = { readonly type: unknown; } & symbol; export type GetDep0<S> = S extends Dep0 ? S["type"] : never; // 抽象の定義に型引数が含まれる場合は, それに対応した `Dep1`, `Dep2` を追加していく
次に, DepRegistry クラスを追加する. これは特定の抽象型 (type Hoge = { ... } や interaface Hoge { ... }) に対応する Symbol をキーに, その interface を実装したオブジェクトを格納する. 具体的には次のメソッドを提供する.
DepRegistry
type Hoge = { ... }
interaface Hoge { ... }
add<K>(key: K, value: GetDep0<K>): void;
has(key: symbol): boolean;
get<K>(key: K): GetDep0<K>;
remove(key: symbol): void;
clear(): void;
これを利用して, 各モジュールの実装を以下のように書き換える.
module
Dep0
symbol
server/index.ts
No response
機能要望の提出を行う前に
要望の概要
/packages/bot/src/service/command.ts
のregisterAllCommandResponder
は依存関係の注入処理をまとめているが, 明らかに依存関係と引数のサイズが肥大化しており管理が難しい. このまま今後の機能追加や改善は難しいのでこれを改善しつつ, 概念的に共通する依存関係の整理と直感的なサービス実装も維持できるようにしたい.新規実装
まず, ドライバ層として
/packages/bot/src/driver/
フォルダを追加する. そしてその配下にdep-registry.ts
ファイルを追加し, 自前の DI コンテナ実装として依存関係レジストリを表す実装を追加する.特定のシンボルに対応した抽象の型を定義するために, 次の型情報を
export
する. これは後述のSymbol
の追加とinterface
のマージ処理を利用したテクニックである.次に,
DepRegistry
クラスを追加する. これは特定の抽象型 (type Hoge = { ... }
やinteraface Hoge { ... }
) に対応するSymbol
をキーに, そのinterface
を実装したオブジェクトを格納する. 具体的には次のメソッドを提供する.add<K>(key: K, value: GetDep0<K>): void;
- 依存関係を登録する. 上書きしようとすると例外を送出する.has(key: symbol): boolean;
- その依存関係が登録されているかどうかを返す.get<K>(key: K): GetDep0<K>;
- 依存関係を取得する. 存在しないものを取得しようとすると例外を送出する.remove(key: symbol): void;
- 依存関係を削除する. 存在しなくてもエラーにはならない.clear(): void;
- すべての依存関係を削除する.コードの書き換え
これを利用して, 各モジュールの実装を以下のように書き換える.
Symbol
を併せてexport
する. またmodule
記法を用いてDep0
をオーバーライドし, 特定のsymbol
に対応するinterface
の型を TypeScript コンパイラが取り出せるようにする.DepRegistry
のみを受け取るようにする. 必要な依存関係はこの依存関係レジストリを介して取得する.server/index.ts
) ではレジストリDepRegistry
へ特定のシンボルとそれに対応するアダプタ実装を登録し, サービスへレジストリを渡す.代替え案
No response
追加情報
No response