文档依赖关系

依赖关系

声明了标识符和依赖项之后,就需要在依赖项之间声明依赖关系。

有两种依赖项需要声明依赖关系:

  • 类依赖项
  • 工厂函数依赖项

在类依赖项上声明依赖关系

在类依赖项上声明依赖关系,可以用 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]],
    },
  ],
];