依赖关系
声明了标识符和依赖项之后,就需要在依赖项之间声明依赖关系。
有两种依赖项需要声明依赖关系:
- 类依赖项
- 工厂函数依赖项
在类依赖项上声明依赖关系
在类依赖项上声明依赖关系,可以用 Inject
装饰器:
class MapService {
constructor(
@Inject(SatelliteService) private readonly satellite: SatelliteService,
) {}
}
也可以使用 createIdentifier
方法创建的标识符:
interface IPlatformService {}
const IPlatformService = createIdentifier<IPlatformService>("platform");
class DialogService {
constructor(
@IPlatformService private readonly platformSrc: IPlatformService,
) {}
}
可选依赖
如果在实例化一个依赖项时,它的依赖未被注入器所持有,那么就会抛出错误。
class MapService {
constructor(
@Inject(SatelliteService) private readonly satellite: SatelliteService,
) {}
}
const injector = new Injector([[MapService]]);
injector.get(MapService); // ERROR
有时候,你会想在无法获取到一个依赖时仍然能够继续实例化过程(特别是在代码作为 SDK 给其他开发者使用时),此时你应当将 Inject
替换为 Optional
来标记这个依赖是可选的:
class MapService {
constructor(
@Optional(SatelliteService) private readonly satellite?: SatelliteService,
) {}
}
const injector = new Injector([MapService]);
injector.get(MapService);
即使 SatelliteService
未被提供,MapService
仍可以实例化,只是 satellite
属性为 undefined
而已。
多值依赖
类似于可选依赖,可以用 Many
装饰器标识一个标识符注入多个依赖项:
class MapService {
constructor(
@Many(ISatelliteService) private readonly satellites: ISatelliteService[],
) {}
}
const injector = new Injector([
[MapService],
[ISatelliteService, { useClass: GPSSatellite }],
[ISatelliteService, { useClass: BeidouSatellite }],
]);
injector.get(MapService);
在工厂函数依赖项上声明依赖关系
只需要在 deps
中列出即可:
const item = [
I18NNumberTranspiler,
{
useFactory: (i18nService: I18NService) => {
return i18nService.isChinese()
? new ChineseNumberTranspiler()
: new EnglishNumberTranspiler();
},
deps: [[I18NService]],
},
];
工厂函数一样可以声明可选依赖和多值依赖,只是语法会稍有不同:
const item = [
[ISatelliteService, { useClass: GPSSatellite }],
[ISatelliteService, { useClass: BeidouSatellite }],
[
IMapService,
{
useFactory: (satellites: ISatelliteService[]) =>
new MapService(satellites),
deps: [[new Many(), ISatelliteService]],
},
],
];