Is Singleton Instance of a service provided to child components?

1.8k Views Asked by At

Suppose there is a parent component P . Having two child components B and C . I provide a service (MyService let's say) in the ElementInjector of P and Inject the service in the constructor of P component class. I Inject the service again in the two child components B and C .

My question is whether the instance of the service available with B,C and P will be the same in this case ?

And what if I Inject the service only in the two child components B and C and NOT in the parent component P . Will B and C have separate Instances of the MyService service in this case ?

Here is an image to help visualize the components . Parent Component P with Child Components B and C

Edit:

Service class :

@Injectable()
export class MyService(){
   constructor(){
console.log('My Service instantiated');
}
}

P component's class:

import {MyService} from '...';

@Component({

selector:'Pcomp',
...
providers:[MyService]
})

export class PComponent {
 constructor(public myservice:MyService){
}
}

Component B class :

import {MyService} from '...';

@Component({

selector:'Bcomp',
...

})

export class BComponent {
 constructor(public myservice:MyService){
}
}

Component C class:

import {MyService} from '...';

@Component({

selector:'Ccomp',
...
})

export class CComponent {
  constructor(public myservice:MyService){
}
}
2

There are 2 best solutions below

3
juniordevlife On

If you are using angular CLI, service will be generated with something like this

@Injectable({
  providedIn: 'root',
})  

So service is generated as a singleton and that means only one instance can exist int an app. I think it is recommended to create a service as a singleton.

0
bron10 On

Services are/were used as singletons across a module. Since Angular 9, services are something more than just singletons now. what I mean by this is having new instance of service with a lazy loaded module.

Lazy loading is when you load modules only when you need them; for example, when routing.They aren’t loaded right away like with eagerly loaded modules. This means that any services listed in their provider arrays aren’t available because the root injector doesn’t know about these modules. -- angular.io guide

Hence, It all depends on your usage of metadata especially using providedIn in service injectable decorator and providers for component decorator.

In above case, if we limit MyService as a provider to a component, it will be limited to that component. Mentioning a piece of above code as below.

@Component({
    selector:'Pcomp',
...
    providers:[MyService]
})

As provider is at Pcomp level, Pcomp and its descendant Bcomp and Ccomp can leverage MyService as a singleton.

Reference : https://angular.io/guide/providers#limiting-provider-scope-with-components