我的应用程序中有一个@Injectable
服务,该服务已添加为AppModule
中的提供程序。我想确保我的开发团队中没有人在任何其他模块中注入它。单个实例就足够了,它有一些复杂的逻辑,我不想运行两次。有什么想法吗?
我知道DI在角度2中是如何工作的,所以答案如下:'确保它仅作为提供者添加到App Module'没有帮助。 :(
请注意,如果将服务提供给除AppModule以外的任何其他服务,我希望它在构建或运行时产生某种错误。
答案 0 :(得分:7)
Angular为每个提供商维护一个实例。
确保您只提供一次服务,DI将确保您的应用程序中只有一个实例。
如果您在组件@Component({ ..., providers: [...]})
上提供服务,那么组件实例的实例数将与实例一样多。
如果您仅在导入providers
的{{1}} AppModule
或providers
个模块中提供服务,那么整个应用程序只会有一个实例:
AppModule
陷阱是延迟加载的模块。如果模块是延迟加载的,那么提供的提供程序将导致创建另一个实例,因为延迟加载的模块具有自己的DI根范围。
对于延迟加载的模块,实现@NgModule({
providers: [...],
imports: [...]
})
export class AppModule {}
并仅在forRoot()
中添加应用程序范围的单例,而不是forRoot()
中的提供者,并将其导入providers
AppModule
<强>更新强>
要防止实例化多个服务实例,您可以使用
等变通方法@NgModule({
providers: [...],
imports: [LazyLoadedModuleWithSingltonProvider.forRoot()]
})
export class AppModule {}
另一种方法是将单件服务移动到@Injectable()
export class MyService {
private static instanceCounter = 0;
private instanceNumber = instanceCounter++;
constructor() {
if(this.instanceNumber > 0) {
throw 'MyService must be kept a singleton but more than one instance was created';
}
}
}
并阻止在CoreModule
https://angular.io/docs/ts/latest/guide/ngmodule.html#!#prevent-reimport
只有根AppModule才能导入CoreModule。如果延迟加载的模块导入它,则会发生错误。