我的@Injectable
应用程序中有一个服务,作为提供程序添加AppModule
.我想确保我的开发团队中没有人在任何其他模块中注入它.单个实例就足够了,它有一些复杂的逻辑,我不想运行两次.有任何想法吗?
我知道DI在角度2中是如何工作的,所以像'确保它仅作为提供者添加在App模块中'这样的答案将无济于事.:(
请注意,如果将服务提供给除AppModule之外的任何其他服务,我希望它在构建或运行时产生某种错误.
Angular为每个提供程序维护一个实例.
确保您只提供一次服务,DI将确保您的应用程序中只有一个实例.
如果@Component({ ..., providers: [...]})
为组件提供服务,则组件实例将具有尽可能多的实例.
如果仅在提供服务providers
的AppModule
或providers
进口的模块AppModule
,那么只会有你的整个应用程序的单一实例:
@NgModule({
providers: [...],
imports: [...]
})
export class AppModule {}
陷阱是延迟加载的模块.如果模块是延迟加载的,那么提供的提供者将导致创建另一个实例,因为延迟加载的模块具有它们自己的DI根范围.对于延迟加载的模块,实现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';
}
}
}
另一种方法是将单件服务移动到a CoreModule
并防止该模块被导入到除了之外的任何地方AppModule
https://angular.io/docs/ts/latest/guide/ngmodule.html#!#prevent-reimport
只有根AppModule才能导入CoreModule.如果延迟加载的模块导入它,则会发生错误.