3

I have a service for sharing data between components and other services. I'm injecting it into components and services with angular's DI. The service stores some data in its properties (non-statically). I also user a ComponentResolver to dynamically create and load components and then destroy them. The problem is ... if i inject such a service in a component using simply:

constructor(private myService: MyDataService) { ... }

A new instance of this server is injected each time and the data is lost. I could store the data statically, but then there are observers that subscribe to this data. Long story short - too many things to refactor into static variables. Is there some sort of way to tell angular's DI to only create one instance of this service and share it in every single injection?

1 Answer 1

1

This is because Angulars DI maintains a single instance per provider

If you provide the service only once (root component or bootstrap()) then there will be only one instance and every service or component that injects it will get the same instance.

update

Yes, you have to use

@NgModule({
  providers: [MyService],
  ...,
})
export class AppModule {}

or

@Component({ 
  selector: 'my-app', 
  providers: [MyService], 
  ...
})
export class AppComponent {}

(or alternatively viewProviders)

to provide injectables, but if you want to have singletons ensure that you provide an injectable only once.

If you provide the same injectable more than once, than the component where you provide it and all its descendants get the instance from this provider, instead of the one from an ancestor where it might be also provided.

DI is hierarchical and looks from the current component towards root component and AppModule for a provider. It injects the instance from the first provider it finds this way.

Sign up to request clarification or add additional context in comments.

4 Comments

Right, Don't you have to use the boostrap or at least a view provider to use the DI in the constructor? It's my understanding that all Injected services are singletons, I didn't know it was possible to do it as new instances..
I updated my answer because it was to long for a comment.
@GünterZöchbauer but is there a way to force an Injectable to be provided only in AppComponent and not others?
No, there is no way to do that. You can "override" at a lower level, but you can not enforce a specific instance from a higher level.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.