Dependency Injection (DI) is a core design pattern in Angular that allows you to inject services and other dependencies into components, directives, pipes, and other services — without hard-coding their creation. This makes your app more modular, testable, and maintainable.
At its core:
Angular uses an Injector to create and deliver dependencies.
When a class declares a dependency (usually in its constructor), Angular looks for a provider of that dependency and injects it.
✅ Example:
In this case, AuthService
is injected into LoginComponent
.
๐️ Providers: Where the Magic Happens
A provider tells Angular how to create a dependency. It can be declared at different levels:
@Injectable({ providedIn: 'root' })
— Singleton, app-wide (preferred).Inside component/directive metadata (
providers: [...]
)In
NgModule
metadata
๐งฑ Hierarchical Injectors in Angular
Angular’s DI system is hierarchical, meaning there are multiple injectors arranged in a tree-like structure that matches the component tree.
๐ Injector Hierarchy:
Root injector (global, app-wide)
Module injectors (scoped to NgModules)
Component injectors (scoped to component and its children)
When Angular needs to resolve a dependency, it:
Checks the component’s own injector (if defined in
providers
).If not found, walks up the tree toward the root injector.
✅ Real-World Example
If
WidgetComponent
is a child ofDashboardComponent
, it gets a new instance ofLoggerService
.If
LoggerService
was provided in the root,WidgetComponent
would share the same instance app-wide.
๐ฏ Why Hierarchical Injectors Matter
๐ Reusability & Encapsulation
You can scope services to components for isolation (e.g., local state, logging).
๐งช Testing
Easier to mock or override services at component level.
⚠️ Potential Pitfall
Accidentally declaring a service in multiple component
providers
can lead to unexpected multiple instances.
๐ Summary
Concept | Description |
---|---|
Dependency Injection | Angular automatically injects required services via constructors |
Injector | Registry that maps tokens to service instances |
Root Injector | Global scope; services provided in 'root' |
Hierarchical Injectors | Each component/module can have its own injector (child of parent) |
Service Scope | Controls how many instances of a service are created and where shared |