How to use dependency injection in Angular

Dependency injection in Angular provides automatic service instantiation and dependency management, enabling loose coupling and testable code architecture across components and services. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented dependency injection patterns in thousands of Angular applications for scalable enterprise architecture and maintainable code structures. From my expertise, the most effective approach is using Angular’s built-in DI system with proper provider configuration and injection tokens. This method provides automatic dependency resolution with clean separation of concerns and efficient service lifecycle management.

Use Angular’s dependency injection system with providers and injection tokens for automatic service instantiation.

import { Injectable, Inject, InjectionToken } from '@angular/core'
import { HttpClient } from '@angular/common/http'

// Create injection token for configuration
export const API_CONFIG = new InjectionToken<ApiConfig>('api.config')

export interface ApiConfig {
  baseUrl: string
  timeout: number
}

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  constructor(
    private http: HttpClient,
    @Inject(API_CONFIG) private config: ApiConfig
  ) {}

  getData(endpoint: string) {
    return this.http.get(`${this.config.baseUrl}/${endpoint}`, {
      timeout: this.config.timeout
    })
  }
}

// In app.module.ts or providers array
providers: [
  {
    provide: API_CONFIG,
    useValue: {
      baseUrl: 'https://api.example.com',
      timeout: 5000
    }
  }
]

// In component
@Component({
  selector: 'app-data',
  template: '<div>Loading data...</div>'
})
export class DataComponent {
  constructor(private apiService: ApiService) {}

  ngOnInit() {
    this.apiService.getData('users').subscribe(data => {
      console.log('Users:', data)
    })
  }
}

Angular’s DI system automatically resolves dependencies based on constructor parameters and provider configuration. Use @Inject() decorator for custom injection tokens and configure providers in modules or component providers array. The DI container manages service lifecycles and ensures singleton behavior for root-provided services.

Best Practice Note:

This is the same dependency injection architecture we use in CoreUI Angular components for clean service management and testable code across enterprise applications.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author