前回の続きです。
scoped
を試す
DIコンテナにはインスタンスの生存期間を管理するためにスコープという概念がありますが、TSyringe
ではどのようになっているか実際に動かして確認してみます。
まずスコープ別に4つ用意します。
scopedComponents/SingletonComponent.ts
import { singleton } from "tsyringe";
@singleton()
export default class SingletonComponent {
constructor() {
console.log("new SingletonComponent()")
}
}
scopedComponents/ContainerComponent.ts
import { scoped, Lifecycle } from "tsyringe";
@scoped(Lifecycle.ContainerScoped)
export default class ContainerComponent {
constructor() {
console.log("new ContainerComponent()")
}
}
scopedComponents/ResolutionComponent.ts
import { scoped, Lifecycle } from "tsyringe";
@scoped(Lifecycle.ResolutionScoped)
export default class ResolutionComponent {
constructor() {
console.log("new ResolutionComponent()")
}
}
scopedComponents/InjectableComponent.ts
import { injectable } from "tsyringe";
@injectable()
export default class InjectableComponent {
constructor() {
console.log("new InjectableComponent()")
}
}
これらをインジェクションしているクラスを親子で用意
ChildService.ts
import { injectable } from "tsyringe";
import SingletonComponent from "./scopedComponents/SingletonComponent";
import ContainerComponent from "./scopedComponents/ContainerComponent";
import ResolutionComponent from "./scopedComponents/ResolutionComponent";
import InjectableComponent from "./scopedComponents/InjectableComponent";
@injectable()
export default class ChildService {
constructor(
private singleton: SingletonComponent,
private container: ContainerComponent,
private resolution: ResolutionComponent,
private injectable: InjectableComponent
) {
console.log("new ChildService()")
}
}
ParentService.ts
import { injectable } from "tsyringe";
import ChildService from "./ChildService";
import SingletonComponent from "./scopedComponents/SingletonComponent";
import ContainerComponent from "./scopedComponents/ContainerComponent";
import ResolutionComponent from "./scopedComponents/ResolutionComponent";
import InjectableComponent from "./scopedComponents/InjectableComponent";
@injectable()
export default class ParentService {
constructor(
private childService: ChildService,
private singleton: SingletonComponent,
private container: ContainerComponent,
private resolution: ResolutionComponent,
private injectable: InjectableComponent
) {
console.log("new ParentService()")
}
}
そして最後にエントリポイント
index.ts
import "reflect-metadata";
import { container } from "tsyringe";
import ParentService from "./ParentService";
console.log("-----parentService1回目")
container.resolve(ParentService);
console.log("-----parentService2回目")
container.resolve(ParentService);
実行結果は以下のようになりました。
-----parentService1回目
new SingletonComponent()
new ContainerComponent()
new ResolutionComponent()
new InjectableComponent()
new ChildService()
new InjectableComponent()
new ParentService()
-----parentService2回目
new ResolutionComponent()
new InjectableComponent()
new ChildService()
new InjectableComponent()
new ParentService()
-
injectable
はParentService
,ChildService
両方でインスタンス生成 -
Resolution
はresoluve
要求につき1個生成 -
singleton
,Container
は2回目には含まれていないことから1つのインスタンスが再利用されている
ということがわかります。
ドキュメントによると Container
はsingleton
と似ていますが、子コンテナを作ったときは子コンテナで一つのインスタンスが作られるようです。
子コンテナを作ってみる
ということなので実際に子コンテナを作って動かしてみます。
エントリポイントのみ変更しました。
しつこく親子2回ずつ実行してみます。
index.ts
import "reflect-metadata";
import { container } from "tsyringe";
import ParentService from "./ParentService";
console.log("-----parentService1回目(親コンテナから)")
container.resolve(ParentService);
console.log("-----parentService2回目(子コンテナから)")
const childContainer1 = container.createChildContainer();
childContainer1.resolve(ParentService);
console.log("-----parentService3回目(親コンテナから)")
container.resolve(ParentService);
console.log("-----parentService4回目(子コンテナから)")
childContainer1.resolve(ParentService);
実行結果
-----parentService1回目(親コンテナから)
new SingletonComponent()
new ContainerComponent()
new ResolutionComponent()
new InjectableComponent()
new ChildService()
new InjectableComponent()
new ParentService()
-----parentService2回目(子コンテナから)
new ContainerComponent()
new ResolutionComponent()
new InjectableComponent()
new ChildService()
new InjectableComponent()
new ParentService()
-----parentService3回目(親コンテナから)
new ResolutionComponent()
new InjectableComponent()
new ChildService()
new InjectableComponent()
new ParentService()
-----parentService4回目(子コンテナから)
new ResolutionComponent()
new InjectableComponent()
new ChildService()
new InjectableComponent()
new ParentService()
-
new SingletonComponent()
は1回のみ -
new ContainerComponent()
は1,2回目のみ
ということが確認できました。
続きはこちら