Dependency Injection in Angular

Estimated study time: 14 minutes. The design pattern that powers how Angular components get their dependencies.

Dependency Injection (DI) is a design pattern where a class receives its dependencies from an external source rather than creating them itself. Angular's DI system is built into the framework's core.

Why Dependency Injection?

Without DI, a component would need to manually instantiate every service it uses — tightly coupling it to specific implementations and making testing painful. With DI, Angular hands a component whatever it declares it needs.

A Basic Example

@Injectable({ providedIn: 'root' })
export class LoggerService {
  log(message: string) { console.log('[LOG]', message); }
}

@Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html' })
export class DashboardComponent {
  constructor(private logger: LoggerService) {
    this.logger.log('Dashboard initialized');
  }
}

Angular sees LoggerService in the constructor and automatically supplies an instance — you never call new LoggerService() yourself.

How the Injector Works

Angular maintains a hierarchical tree of injectors. When a component asks for a dependency, Angular looks for a matching provider starting at the component's own injector, then walks up through its parent injectors until it finds one (or reaches the root).

Providing a Service

// App-wide singleton
@Injectable({ providedIn: 'root' })
export class AuthService {}

// Scoped to a specific module
@NgModule({ providers: [FeatureService] })
export class FeatureModule {}

// Scoped to a specific component and its children
@Component({ providers: [LocalCacheService] })
export class SomeComponent {}

Injection Tokens

For dependencies that aren't classes — like a configuration object or a primitive value — Angular uses InjectionToken to identify what to inject.

export const API_URL = new InjectionToken<string>('API_URL');

providers: [{ provide: API_URL, useValue: 'https://api.example.com' }]

constructor(@Inject(API_URL) private apiUrl: string) {}
💡 Tip: Use providedIn: 'root' for most services — it's tree-shakable, meaning Angular removes it from the final bundle entirely if nothing ever injects it.

Ready to go beyond the basics?

Get hands-on training, live mentorship, and placement support with Uncodemy's Angular Training Course.

Explore Angular Training Course →