Angular 2:如何在应用程序中强制注射器成为单例
Angular 2: how to force an injectable to be a singleton in the app
我的应用程序中有一个 @Injectable
服务,它作为提供程序添加到 AppModule
中。我想确保我的开发团队中没有人将它注入任何其他模块。一个实例就足够了,它有一些复杂的逻辑,我不想 运行 两次。有什么想法吗?
我知道 DI 在 angular 2 中是如何工作的,所以像 'Make sure it is added as a provider only in App Module' 这样的回答没有帮助。 :(
请注意,如果服务提供给除 AppModule 之外的任何其他服务,我希望它在构建或 运行 时产生某种错误。
Angular 每个提供商维护一个实例。
确保您只提供一次服务,DI 将确保您的应用程序中只有一个实例。
如果您在组件 @Component({ ..., providers: [...]})
上提供服务,那么实例数将与组件实例数一样多。
如果您仅在 AppModule
的 providers
或导入到 AppModule
的模块的 providers
中提供服务,那么您的整个实例将只有一个实例申请:
@NgModule({
providers: [...],
imports: [...]
})
export class AppModule {}
延迟加载模块是一个陷阱。如果一个模块是延迟加载的,那么那里提供的提供者将导致创建另一个实例,因为延迟加载的模块有自己的 DI 根范围。
对于延迟加载的模块,实现 forRoot()
并添加应该是 application-wide 单例的提供程序,仅在 forRoot()
中,而不是在 providers
中,并将其导入 AppModule
[=26] =]
@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
并防止此模块在 AppModule
之外的任何其他地方导入
https://angular.io/docs/ts/latest/guide/ngmodule.html#!#prevent-reimport
Only the root AppModule should import the CoreModule. Bad things happen if a lazy loaded module imports it.
我的应用程序中有一个 @Injectable
服务,它作为提供程序添加到 AppModule
中。我想确保我的开发团队中没有人将它注入任何其他模块。一个实例就足够了,它有一些复杂的逻辑,我不想 运行 两次。有什么想法吗?
我知道 DI 在 angular 2 中是如何工作的,所以像 'Make sure it is added as a provider only in App Module' 这样的回答没有帮助。 :(
请注意,如果服务提供给除 AppModule 之外的任何其他服务,我希望它在构建或 运行 时产生某种错误。
Angular 每个提供商维护一个实例。
确保您只提供一次服务,DI 将确保您的应用程序中只有一个实例。
如果您在组件 @Component({ ..., providers: [...]})
上提供服务,那么实例数将与组件实例数一样多。
如果您仅在 AppModule
的 providers
或导入到 AppModule
的模块的 providers
中提供服务,那么您的整个实例将只有一个实例申请:
@NgModule({
providers: [...],
imports: [...]
})
export class AppModule {}
延迟加载模块是一个陷阱。如果一个模块是延迟加载的,那么那里提供的提供者将导致创建另一个实例,因为延迟加载的模块有自己的 DI 根范围。
对于延迟加载的模块,实现 forRoot()
并添加应该是 application-wide 单例的提供程序,仅在 forRoot()
中,而不是在 providers
中,并将其导入 AppModule
[=26] =]
@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
并防止此模块在 AppModule
https://angular.io/docs/ts/latest/guide/ngmodule.html#!#prevent-reimport
Only the root AppModule should import the CoreModule. Bad things happen if a lazy loaded module imports it.