Back to course

Understanding Dependency Injection (DI)

The Complete Angular Developer: From Zero to Hero

21. Understanding Dependency Injection (DI)

Dependency Injection (DI) is a core design pattern in Angular. It allows a class (the dependent) to receive its dependencies (other objects it needs to perform its function) from an external source, rather than creating them itself.

Why Use DI?

  1. Reusability: Services can be reused across different components.
  2. Testability: Easier to swap real dependencies with mock implementations during testing.
  3. Maintainability: Decouples components from their dependencies, reducing complexity.

The Three Parts of DI

  1. The Consumer/Dependent: The component or service that needs the dependency (e.g., a ProductComponent needs a ProductService).
  2. The Dependency: The class that provides the required functionality (e.g., ProductService).
  3. The Injector: Angular's built-in mechanism that creates and manages the dependency instances and injects them into the consumer.

How Angular Handles Injection

Angular's Injector maintains a map of tokens (usually the class type) to providers (recipes for creating the instance).

When a component requests a dependency via its constructor, Angular looks for a matching provider in its injection tree (starting at the component level and moving up to the module, and finally the root).

Example of requesting a dependency:

typescript import { LoggerService } from './logger.service';

// Angular reads the constructor parameter and tries to fulfill the dependency export class MyComponent { constructor(private logger: LoggerService) { // The logger instance is provided by Angular's injector this.logger.log('Component initialized.'); } }