Injector Hierarchy in Angular
What is Injector Hierarchy in Angular?
In Angular dependency injection (Dependency Injection, DI) is built on injector hierarchy, where dependencies can be available:
- Globally
- Only within module
- Only in component
- Only in specific directive or pipe
Angular creates injector tree, similar to component tree. Each component can have own injector, inherited from parent.
Injector Hierarchy Levels
Global Level — @Injectable({ providedIn: 'root' })
- Service is created once for entire application.
- Available everywhere without need to specify in
providers.
@Injectable({ providedIn: 'root' })
export class LoggerService {}
Used by default for singleton services.
Module Level (in @NgModule.providers)
- Service is available only within specified module.
- If module is imported into other modules — behavior may differ.
@NgModule({
providers: [AuthService]
})
export class AuthModule {}
Good for limited access and lazy-loaded modules.
Component Level (in @Component.providers)
- Service is created separately for each component instance.
- Suitable for local state, independent from other components.
@Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
providers: [CartService]
})
export class CartComponent {}
For each component usage new instance of service will be created.
Directive/Pipe Level (@Directive.providers)
- Similarly to components — service is created locally, inside element where directive is applied.
@Directive({
selector: '[highlight]',
providers: [HighlightService]
})
export class HighlightDirective {}
How Angular Searches Dependencies
When Angular injects dependency, it:
- First looks in component's local injector.
- If not found — searches in parent injector.
- And so on up to root injector (
root). - If dependency not found — throws error.
Example: nested components and different injectors
@Component({
selector: 'parent',
providers: [SharedService],
template: `<child></child>`
})
export class ParentComponent {}
@Component({
selector: 'child',
template: `...`
})
export class ChildComponent {
constructor(shared: SharedService) {} // will get instance from parent
}
If SharedService is not specified in child, it will be inherited from parent.