This document describes Angular's hierarchical dependency injection (DI) system, which provides services and values to components, directives, and other injectables throughout the application. The DI system manages service instantiation, dependency resolution, and lifecycle management through a hierarchy of injectors.
For information about application bootstrapping and initialization, see Application Lifecycle and Bootstrap. For details on change detection and scheduling, see Change Detection Strategies.
Angular's DI system is built on a hierarchical injector tree that mirrors the component tree structure. The system uses token-based lookup with optimizations like Bloom filters for fast dependency resolution. Providers are configured at various levels (environment, component, element) and can be resolved through multiple injector types working together.
Key Characteristics:
InjectionToken, Type, or abstract classes packages/core/src/application/application_ref.ts62-64@Injectable() (and the internal @Service()) allows tools to remove unused services adev/src/content/guide/di/hierarchical-dependency-injection.md27-33Sources: adev/src/content/guide/di/hierarchical-dependency-injection.md1-50 packages/core/src/application/application_ref.ts62-64
Angular maintains two primary injector hierarchies that work together during dependency resolution.
Diagram: Logical Injector Hierarchy
| Injector Type | Purpose | Configuration |
|---|---|---|
NullInjector | The ultimate parent; throws an error unless @Optional() is used adev/src/content/guide/di/hierarchical-dependency-injection.md64-83 | Internal |
PlatformInjector | Shared across multiple applications on a page (e.g., DomSanitizer) adev/src/content/guide/di/hierarchical-dependency-injection.md75-78 | platformBrowser() |
EnvironmentInjector | Application-wide services. Includes the root injector adev/src/content/guide/di/hierarchical-dependency-injection.md20-26 | @Injectable({providedIn: 'root'}), ApplicationConfig.providers |
ElementInjector | Scoped to a specific DOM element and its children adev/src/content/guide/di/hierarchical-dependency-injection.md117-130 | @Component.providers, @Directive.providers |
Sources: adev/src/content/guide/di/hierarchical-dependency-injection.md9-95 packages/core/src/platform/platform_ref.ts32-39
In the Ivy runtime, ElementInjector is implemented via the NodeInjector. It is tightly coupled with the LView (Logical View) and TView (Template View) structures.
Diagram: ivy NodeInjector Implementation
The NodeInjector uses Bloom filters to perform high-speed checks for token existence before traversing the hierarchy. If the Bloom filter bit for a token is not set, the system skips the current injector entirely packages/core/src/render3/instructions/change_detection.ts205-207
Sources: packages/core/src/render3/instructions/change_detection.ts180-210 packages/core/src/render3/debug/injector_profiler.ts50-54
Angular supports multiple provider formats to define how a dependency should be created.
| Provider Type | Declaration | Implementation |
|---|---|---|
| Class Provider | { provide: Logger, useClass: BetterLogger } | Instantiates a class packages/core/test/acceptance/injector_profiler_spec.ts204-206 |
| Value Provider | { provide: API_URL, useValue: 'http://...' } | Returns a static value packages/core/test/acceptance/injector_profiler_spec.ts170-172 |
| Factory Provider | { provide: TOKEN, useFactory: () => ... } | Executes a function to create the value packages/core/test/acceptance/injector_profiler_spec.ts204-206 |
| Existing Provider | { provide: Logger, useExisting: NewLogger } | Creates an alias to another token packages/core/test/acceptance/injector_profiler_spec.ts204-206 |
Sources: packages/core/test/acceptance/injector_profiler_spec.ts15-40 packages/core/test/acceptance/injector_profiler_spec.ts162-177
The compiler generates metadata for classes decorated with @Injectable or @Service.
ɵɵdefineInjectable: Defines how a service is constructed and its scope (e.g., root) packages/core/src/core_private_export.ts73-77ɵɵdefineInjector: Defines the providers and imports for an injector (used in NgModule or ApplicationConfig) packages/core/src/core_private_export.ts73-77Sources: packages/core/src/core_private_export.ts73-77 packages/core/src/di/interface/defs.ts1-10 (inferred from exports)
inject() FunctionThe inject() function is the primary way to retrieve dependencies in modern Angular. It must be called within an Injection Context (e.g., constructor, factory, or field initializer) packages/core/src/application/application_ref.ts24-27
Diagram: inject() Resolution Path
Key resolution rules:
@Optional(): Returns null instead of throwing if not found adev/src/content/guide/di/hierarchical-dependency-injection.md81-83@Self(): Only searches the current ElementInjector.@SkipSelf(): Starts the search at the parent injector packages/core/test/acceptance/injector_profiler_spec.ts174-177@Host(): Stops search at the host component.Sources: packages/core/src/application/application_ref.ts24-27 adev/src/content/guide/di/hierarchical-dependency-injection.md64-95 packages/core/test/acceptance/injector_profiler_spec.ts162-177
Angular provides internal hooks for profiling the DI system, primarily used by DevTools.
The injectorProfiler is a global hook that intercepts DI events packages/core/src/render3/debug/injector_profiler.ts47-54
Monitored Events:
Inject: Triggered when inject() is called packages/core/test/acceptance/injector_profiler_spec.ts87-92InstanceCreatedByInjector: Triggered when a new service instance is instantiated packages/core/test/acceptance/injector_profiler_spec.ts93-98ProviderConfigured: Triggered when a provider is registered in an injector packages/core/test/acceptance/injector_profiler_spec.ts99-104Sources: packages/core/src/render3/debug/injector_profiler.ts43-54 packages/core/test/acceptance/injector_profiler_spec.ts65-111
Dependency Injection is often used to provide the ChangeDetectionScheduler, which orchestrates how the application reacts to changes.
provideZonelessChangeDetection() to inject a scheduler that doesn't rely on Zone.js packages/core/test/change_detection_scheduler_spec.ts33-35provideZoneChangeDetection() to inject the standard NgZone and its associated scheduler packages/core/src/change_detection/scheduling/ng_zone_scheduling.ts153-155Sources: packages/core/src/change_detection/scheduling/zoneless_scheduling_impl.ts59-66 packages/core/src/change_detection/scheduling/ng_zone_scheduling.ts37-41
| Entity | Role | File |
|---|---|---|
ApplicationRef | Coordinates application-level DI and change detection | packages/core/src/application/application_ref.ts163-185 |
EnvironmentInjector | Specialized injector for application environments | packages/core/src/di/r3_injector.ts27-28 |
PlatformRef | Manages the platform-level injector | packages/core/src/platform/platform_ref.ts33-39 |
RouterOutlet | Dynamically creates components using EnvironmentInjector | packages/router/src/directives/router_outlet.ts212-215 |
setInjectorProfiler | Enables/disables DI event tracking | packages/core/src/render3/debug/injector_profiler.ts53-54 |
Sources: packages/core/src/application/application_ref.ts24-27 packages/core/src/platform/platform_ref.ts32-39 packages/router/src/directives/router_outlet.ts212-215 packages/core/src/render3/debug/injector_profiler.ts43-54
Refresh this wiki