Dependency injection is a design pattern dependencies (objects or services) are provided to a class instead of instantiated within the class itself. This promotes the Inversion of Control (IoC) principle, making the application more modular and testable.
Key Benefits of DI:
- Loose Coupling: Components depend on abstractions rather than concrete implementations.
- Reusability: Services can be injected wherever needed.
- Easier Testing: Mocks and stubs can be easily provided in unit tests.
- Better Maintainability: Dependency management is centralized.
Using DI with Services in Angular
Services in Angular are singleton objects that share common functionality across multiple components. They are typically used for:
- API calls
- Data sharing between components
- Business logic processing
Creating a Service with DI
To create a service in Angular, use the CLI:
ng generate service example
This creates example.service.ts:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root', // Makes it available application-wide
})
export class ExampleService {
constructor() {}
getMessage() {
return 'Hello from the service!';
}
}
Injecting a Service into a Component
You can inject the service into a component using the constructor:
import { Component } from '@angular/core';
import { ExampleService } from './example.service';
@Component({
selector: 'app-example',
template: '<p>{{ message }}</p>'
})
export class ExampleComponent {
message: string;
constructor(private exampleService: ExampleService) {
this.message = this.exampleService.getMessage();
}
}
While services are the most common way to use DI, you can also inject dependencies into directives, pipes, guards, interceptors, and even modules.