In the latest release of Angular 6, a service is registered in a module using the providedIn
property in the service metadata:
@Injectable({
providedIn: 'root',
})
export class HeroService {}
However the documentation still also refers to registering the service in the module providers
array in the module metadata just like we did in Angular 5:
@NgModule({
providers: [HeroService],
})
export class AppModule {}
So,
providers
array method be deprecated?providedIn is the new Angular way of doing DI. providedIn was brought since Angular 6. The official name is "Tree-shakeable providers" - instead of module providing all its services, it is now the service itself declaring where it should be provided.
As explained above, the main difference is that between the two methods, providedIn supports tree-shaking, and providers array does not.
The providedIn allow us to specify how Angular should provide the dependency in the service class itself instead of in the Angular Module. It also helps to make the service tree shakable i.e. remove the service from the final bundle if the app does not use it.
ProvidedIn: any That means there might be multiple instances of the same service. That means that every lazy loaded module has it's own instance of the service. All eagerly loaded modules share one instance provided by the root module injector.
Basically you can use either, But as per new CLI provideIn
will be automatically added while creating service
#providedIn
There is now a new, recommended, way to register a provider, directly inside the
@Injectable()
decorator, using the new providedIn attribute. It accepts'root'
as a value or any module of your application. When you use'root'
, your injectable will be registered as a singleton in the application, and you don’t need to add it to the providers of the root module. Similarly, if you useprovidedIn: UsersModule
, the injectable is registered as a provider of theUsersModule
without adding it to the providers of the module.This new way has been introduced to have a better tree-shaking in the application. Currently a service added to the providers of a module will end up in the final bundle, even if it is not used in the application, which is a bit sad.
For more information please refer here
As always when multiple solutions are available it depends on what you want to achieve. But the documentation gives you some directive to choose.
Sometimes it's not desirable to have a service always be provided in the application root injector. Perhaps users should explicitly opt-in to using the service, or the service should be provided in a lazily-loaded context. In this case, the provider should be associated with a specific
@NgModule class
, and will be used by whichever injector includes that module.
So basically you will use providedIn: 'root'
for any services that are application wide. For other services keep using the old version.
Don't forget that on you already had the choice to provide service differently. For instance it's also possible to declare Injectable at component level (this doesn't change in V6).
@Component({
selector: 'app-my-component',
templateUrl: './my.component.html',
providers: [ MyService ]
})
This way the service becomes available only in MyComponent
and its sub-component tree.
If You are using angular 5+ developer, it will automatically create the injectable service when declared as providedIn: 'root', in this case you will not required to import the service in app.module.ts. You can directly use it in another component.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With