How to use dependency injection in Angular
Understanding dependency injection is fundamental for building maintainable Angular applications with loosely coupled components and testable services. As the creator of CoreUI, a widely used open-source UI library, I’ve architected dependency injection patterns in countless Angular applications over 25 years of development. From my expertise, the most effective approach is using Angular’s built-in DI system with proper provider configuration and injection tokens. This creates scalable applications with clear separation of concerns and excellent testability.
Use Angular’s DI system by configuring providers and injecting dependencies through constructors.
@Injectable({ providedIn: 'root' })
export class ApiService {
constructor(private http: HttpClient) {}
}
@Component({})
export class UserComponent {
constructor(private apiService: ApiService) {}
}
Here the @Injectable decorator marks ApiService as available for injection, while providedIn: 'root' makes it a singleton across the application. The UserComponent receives ApiService through constructor injection, and Angular’s DI system automatically provides the instance. This creates loose coupling and makes components easily testable by allowing mock services in tests.
Best Practice Note:
This is the same DI architecture we use throughout CoreUI Angular components for maintainable and testable code. Always use interface-based injection for better abstraction, and configure providers at the appropriate level (root, module, or component) based on the service’s scope and lifecycle requirements.



