How Dependency Injection Works in Angular: Simple Explanation
In Angular,
dependency injection automatically provides components or services with the objects they need by declaring them as constructor parameters. Angular's injector creates and shares these dependencies, making code easier to manage and test.Syntax
Dependency injection in Angular uses the constructor of a class to declare dependencies. Angular's injector reads these declarations and provides the required instances automatically.
constructor(private serviceName: ServiceType): Declares a dependency.@Injectable(): Marks a class as available for injection.providers: Registers services with Angular's injector.
typescript
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class DataService { getData() { return 'Hello from DataService'; } } import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `{{ message }}` }) export class AppComponent { message: string; constructor(private dataService: DataService) { this.message = this.dataService.getData(); } }
Example
This example shows a service DataService injected into a component AppComponent. The component uses the service to get a message and display it.
typescript
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class DataService { getData() { return 'Hello from DataService'; } } import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `<h1>{{ message }}</h1>` }) export class AppComponent { message: string; constructor(private dataService: DataService) { this.message = this.dataService.getData(); } }
Output
<h1>Hello from DataService</h1>
Common Pitfalls
Common mistakes when using dependency injection in Angular include:
- Not adding
@Injectable()to services, so Angular can't inject them. - Forgetting to register services in
providersor usingprovidedInincorrectly. - Trying to inject services without declaring them in the constructor.
- Creating multiple instances by providing services in components instead of at root level.
typescript
/* Wrong: Missing @Injectable decorator */ export class WrongService { getData() { return 'No Injectable'; } } /* Right: Add @Injectable to allow injection */ import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class RightService { getData() { return 'Injectable Service'; } }
Quick Reference
- Use
@Injectable({ providedIn: 'root' })to make services globally available. - Declare dependencies in the constructor with
privateorpublicmodifiers. - Angular injector creates and shares instances automatically.
- Register services in
providersonly if you want a different scope.
Key Takeaways
Angular uses constructor parameters to inject dependencies automatically.
Mark services with @Injectable and provide them in root for easy injection.
Avoid missing @Injectable or incorrect provider registration to prevent errors.
Dependency injection improves code modularity and testability.
Use Angular's injector to share single instances across components by default.