Back to all posts

Dependency Injection and Services in Angular


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.