5
votes

I have two services, both are @Injectable. ServiceA is provided to components via the Providers array and works great everywhere. ServiceB is a singleton and is in the Providers array of its module and works great everywhere. ServiceA needs to remain not a singleton, and ServiceB needs to remain a singleton.

My issue is that now I need to access ServiceA from ServiceB, but don't know how to access it. Seems I cannot inject a non-singleton service into a singleton.

Everything I come across tells me to put the service in bootstrap or module declaration but as I mentioned I cannot do that as I need ServiceA to behave as a non-singleton.

// module setup
... providers: [ServiceB]

// non-singleton
@Injectable()
export class ServiceA

// singleton
@Injectable()
export class ServiceB {
  constructor(ServiceA)  // <-- this is the problem area, need to get ServiceA here

I have tried doing something like constructor(Inject(ServiceA) serviceA) but seem to get the same errors with that

Error: DI Error No provider for ServiceA!

  1. How can I "provide" a non-singleton service into a singleton service, where both are @Injectable?
1

1 Answers

5
votes

You can declare ServiceA both in @Component.providers and @NgModule.providers:

  • When injecting ServiceA in a component's constructor, you'll get the component-scoped instance (corresponding to the @Component.providers declaration).
  • When injecting ServiceA in another service's constructor (in your case: when injecting ServiceA in ServiceB), you'll get the global instance (corresponding to the @NgModule.providers declaration).

In other words, if you redeclare a service in a component's providers (@Component.providers), it will "shadow" the instance that was declared globally in @NgModule.providers.

WORDS OF CAUTION:

  • If you inject ServiceA into ServiceB AND ServiceC, then B and C would get the same instance of A.
  • As mentioned by Seaal in the comments, organizing the code in this manner might not be aligned with best practices.