我有一个基本服务类,我在各种不同模块(由不同团队制作)中有多个不同的服务,这些服务继承自这个。我想在app启动时调用这些服务中常见的“init”函数。我不想在每个匹配此类型的服务上调用“init”,因为我很懒。
例如,在Java Spring中,我可以简单地使用基类注入整个集合,除了声明注入服务之外没有其他配置:
@Autowired
public void setServices(List<ProductService> productServices) {
for(ProductService service : productServices) {
service.init();
}
}
当然,直接类似的方式不起作用。
constructor(private _productServices: ProductService[]) {
// Does not work
_productServices.forEach(x => x.init());
}
有没有办法在Angular中轻松完成这项工作,还是我注定要手动启动所有服务?
感谢您的帮助。
答案 0 :(得分:1)
以上是这个问题:https://stackblitz.com/edit/angular-esdmif
您需要以不同的方式提供所有服务:假设您有基类(不是接口,因为编译的JavaScript中不存在接口,因此Angular无法找到您想要的服务)和一对从您的基类继承的服务。
然后您提供以下服务:
providers: [
{ provide: BaseService, useClass: AService, multi: true },
{ provide: BaseService, useClass: BService, multi: true },
{ provide: BaseService, useClass: CService, multi: true },
{ provide: BaseService, useClass: DService, multi: true }
]
最后multi: true
参数是必需的。
然后在您的组件中执行:
constructor(@Inject(BaseService) private services: BaseService[]) {
}
但这种方法存在一些问题:
答案 1 :(得分:1)
您可以使用注射令牌和多供应商轻松实现您的目标。使用注射令牌,您甚至可以使用接口进行注射。
创建注入令牌:
export const INIT_SERVICE = new InjectionToken<BaseService>('BaseService');
使用多标志提供令牌服务:
{ provide: INIT_SERVICE, useClass: Derived1Service, multi: true }
注入令牌并初始化您的服务:
constructor(@Inject(INIT_SERVICE) initServices: BaseService[]) {
initServices.forEach(service => service.init());
}
工作示例here