tsyringe 的介绍文章不多,在此记录一些实践
Api: container.resolve
container.resolve 相当于 new ClassName, 但它会自动解析被注入的类, 在此注入的入口是 HogeService 的构造器[以参数形式注入]
注意: 要让一个类可注入,必须使用 @injectable 装饰器, @singleton() 可以代替 @injectable 使用 @autoInjectable 和 injectable 功能相同,但注入口处参数需要可选, 即加 ?号
import "reflect-metadata";
import { container, injectable } from "tsyringe";
// @injectable() 这里可有可无,因为没有被注入需求
class FooService {
public constructor() {
console.log("new FooService()");
}
doFoo(value: string) {
return `${value} : Foo!`;
}
}
@injectable() // @autoInjectable
class HogeService {
constructor(
private fooService: FooService
) {
console.log("new HogeService()");
}
// constructor(
// // 这里不加? new AutoHogeService() 时会出错
// private fooService?: FooService
// ) {
// console.log("new AutoHogeService()");
// }
doHoge(value: string) {
return `${value} : Hoge!`;
}
doHogeFoo(value: string) {
return this.fooService.doFoo(this.doHoge(value));
}
}
//FooService 运行
console.log("---------");
const fooService = container.resolve(FooService);
console.log(fooService.doFoo("test01"));
//HogeService 运行
console.log("---------");
const hogeService = container.resolve(HogeService);
console.log(hogeService.doHogeFoo("test02"));
Api: container.register
container.register 的作用是注册一些内容以供消费
Value provider
import "reflect-metadata";
import { container, injectable, inject } from "tsyringe";
class SystemSetting {
public settingCode: string | null = null;
public settingName: string | null = null;
}
@injectable()
class SandboxService {
constructor(
@inject("systemCode") private systemCode: string,
@inject("setting") private setting: SystemSetting
) {
}
showSystemCode() {
console.log(`systemCode=${this.systemCode}`);
}
showSetting() {
console.log(`Setting[settingCode=${this.setting.settingCode}, settingName=${this.setting.settingName}]`);
}
}
// 注册值
container.register("systemCode", { useValue: "001" });
// 注册对象
const setting = new SystemSetting();
setting.settingCode = "010";
setting.settingName = "it";
container.register("setting", { useValue: setting });
const sandboxService = container.resolve(SandboxService);
sandboxService.showSystemCode();
sandboxService.showSetting();
Class provider
import "reflect-metadata";
import { container, injectable, inject } from "tsyringe";
@injectable()
class FooLogicImpl {
constructor() {
console.log("new FooLogicImpl()");
}
doFoo() {
return "foo";
}
}
@injectable()
class HogeService {
constructor(
@inject("FooLogic") private fooLogic: FooLogicImpl,
) {
console.log("new HogeService()");
}
doService() {
console.log(this.fooLogic.doFoo());
}
}
container.register("FooLogic", { useClass: FooLogicImpl });
const hogeService = container.resolve(HogeService);
hogeService.doService();
useFactory provider
import "reflect-metadata";
import { container, DependencyContainer, injectable } from "tsyringe";
@injectable()
class BarLogic {
constructor() {
console.log("new BarLogic()");
}
doBar() {
return "bar";
}
}
class HogeService {
constructor(
private barLogic: BarLogic
) {
console.log("new HogeService()");
}
doHoge() {
console.log(this.barLogic.doBar());
}
}
container.register("HogeService", {
useFactory: (dependencyContainer: DependencyContainer) => {
console.log("factory!")
const barLogic = dependencyContainer.resolve(BarLogic)
return new HogeService(barLogic);
}
})
console.log("------")
const hogeService1 = container.resolve<HogeService>("HogeService")
hogeService1.doHoge();
console.log("------")
const hogeService2 = container.resolve<HogeService>("HogeService")
hogeService2.doHoge();
// 输出结果
// ------
// factory!
// new BarLogic()
// new HogeService()
// bar
// ------
// factory!
// new BarLogic()
// new HogeService()
// bar
instanceCachingFactory
在前面的例子中,HogeService 工厂函数在你每次请求时都会执行,但是如果使用 instanceCachingFactory,工厂函数的结果会被缓存。
// 定义代码省略...
container.register("HogeService", {
useFactory: instanceCachingFactory<HogeService>((dependencyContainer: DependencyContainer) => {
console.log("factory!")
const barLogic = dependencyContainer.resolve(BarLogic)
return new HogeService(barLogic);
})
})
console.log("------")
const hogeService1 = container.resolve<HogeService>("HogeService")
hogeService1.doHoge();
console.log("------")
const hogeService2 = container.resolve<HogeService>("HogeService")
hogeService2.doHoge();
// 输出结果
// ------
// factory!
// new BarLogic()
// new HogeService()
// bar
// ------
// bar