When using the @Injectable
decorator in Angular, the lifetime of an instance of a class is determined by the scope of its parent injector, which can fall into one of three levels:
- Root Scope: Instances injected via the application injector are initialized once at the start of the application and will persist throughout the entire application's lifetime. While these instances behave like singletons, they can still be injected into other scopes where new instances are created.
For example:
@Injectable({ providedIn: 'root' })
export class MyRootService
{
}
An alternative way to create root-scoped services is by importing a ModuleWithProviders
:
@NgModule()
export class MyModule
{
public static forRoot(): ModuleWithProviders
{
return {
ngModule: MyModule,
providers: [
MyRootService,
],
};
}
}
@NgModule({
imports: [
MyModule.forRoot(),
],
})
export class AppModule
{
}
- Module Scope: Instances injected via the module injector will exist for the duration of their module's lifetime. If this module is imported by lazy loaded modules, a separate instance of the class is created for each module and will be destroyed when the module is destroyed.
For example:
@Injectable({ providedIn: MyModule })
export class MyService
{
}
// or
@Injectable()
export class MyService
{
}
@NgModule({
providers: [
MyService,
],
})
export class MyModule
{
}
- Component Scope: Services listed in a component's providers section will only exist for the lifetime of that component. A new instance is created with each component instantiation.
For example:
@Injectable()
export class MyService
{
}
@Component({
providers: [
MyService,
],
})
export class MyComponent
{
}
The providedIn
syntax is utilized to create tree-shakeable services, optimizing the application bundle by including only services that are actually used in the code.
For further insights on Angular dependency injection, refer to this resource.