providedIn: 'root' is the easiest and most efficient way to provide services since Angular 6:
- The service will be available application wide as a singleton with no need to add it to a module’s providers array (like Angular <= 5).
- If the service is only used within a lazy loaded module it will be lazy loaded with that module
- If it is never used it will not be contained in the build (tree shaked).
For further informations consider reading the documentation and NgModule FAQs
Btw:
- If you don’t want an application-wide singleton, use the provider’s array of a component instead.
- If you want to limit the scope so no other developer will ever use your service outside of a particular module, use the provider’s array of NgModule instead.*
*UPDATE
‘use the provider’s array of NgModule instead’ means to use the providers array of the lazy loaded module, eg:
import { NgModule } from '@angular/core';
import { UserService } from './user.service';
@NgModule({
providers: [UserService],
})
export class UserModule {
}
OR to actually name the module in the injectable decorator:
import { Injectable } from '@angular/core';
import { UserModule } from './user.module';
@Injectable({
providedIn: UserModule,
})
export class UserService {
}
Quote from the docs:
When the router creates a component within the lazy-loaded context,
Angular prefers service instances created from these providers to the
service instances of the application root injector.
Doc ref: https://angular.io/guide/providers#providedin-and-ngmodules