在Angular中将非单例服务注入非单例服务

时间:2018-02-27 17:59:08

标签: angular dependency-injection

如果我想将非单身人士服务注入Angular中的另一个非单身人士服务,会怎样?

假设我有一个使用像这样的ServiceA的ComponentA

@component({
  selector: "componentA",
  providers: [ServiceA]
})
export class ComponentA {
  constructor(private serviceA: ServiceA) {}
}

现在,ServiceA也依赖于ServiceB,所以我需要注入它

@Injectable()
export class ServiceA {
   constructor(private serviceB: ServiceB) {}
}

我如何/在哪里宣布我的ServiceB?在模块中?在那种情况下,这将是一个单身人士? 如果我将它添加到ComponentA中的提供程序,它可以正常工作,但我需要在ComponentA中知道ServiceA依赖于ServiceB,这对我来说似乎不太好。

谢谢!

2 个答案:

答案 0 :(得分:1)

粗略地说,除非您在 providedIn 中有 @Injectable() 选项,否则 Angular 不会将服务视为单例。您可以参考文档了解其工作原理:https://angular.io/api/core/Injectable#providedin

您将遇到的问题是,如果您只是这样做:

@Injectable()
export class ServiceB {
   constructor() {}
}

尝试将 ServiceB 注入 ServiceA 时会抛出错误,因为它没有提供程序。通常,要解决此问题,您需要将 { providedIn: 'root' } 添加到 ServiceB 的 @Injectable()。这会将服务 B 创建为应用程序范围的单例服务。

当您使用 @Component( { providers: [] } ) 时,它会为该组件创建一个实例。但是对于服务,您不能这样做。

您可能会问,为什么 @Injectable() 没有 providers 那样的 @Component() 选项? Angular 团队出于多种原因不想这样做,有关详细信息,请参阅此 github 问题 https://github.com/angular/angular/issues/5622

TLDR:

为了给您提供解决此问题的方法,如果您想控制使用的实例,您可以保持简单并避免完全使用 Angular 的 DI,您可以自己动手:

@Injectable()
export class ServiceA {
   constructor(private serviceB: ServiceB = new ServiceB()) {}
}

编辑:按照@minigeek 的建议,使用 providedIn 您可以使用 any 使每个惰性模块获得它自己的服务实例。

答案 1 :(得分:0)

服务在他们提供的范围内始终是单身人士,因此如果您在模块中提供B,那么对于使用该模块的每个人来说,它都是相同的单身人士。我认为您需要在服务A中直接使用Injector来按照您的方式进行操作。

请参阅https://angular.io/api/core/Injectable