A Modern Approach to Angular Dependency Injection using inject function

cover

Introduction

Dependency Injection (DI) enables developers to build sustainable Angular applications. The inject function which arrived with Angular 14 enables developers to handle dependencies through a simpler and type-safe mechanism. This article presents our findings together with the advantages of this approach. The approach demonstrated in this article will benefit your Angular projects regardless.

Problem

The traditional method of dependency injection in Angular requires developers to specify dependencies through constructor methods. The method of dependency specification results in complex code that makes applications harder to understand and maintain as they expand. The development of extensive Angular applications with intricate components and multiple dependencies makes this issue more severe.

Solutions

The Angular team has developed a CLI schematics command that automatically migrates existing projects.

ng generate @angular/core:inject

Tradinational Dependency Injection

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
})
export class ExampleComponent {
  constructor(private exampleService: ExampleService) {}
}

This approach is familiar to most angular developers. If too many dependencies are injected with the constructor method and there are too many operations in the constructor method, it leads to complexity. Manageability and readability become difficult

The New Dependency Injection

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
})
export class ExampleComponent {
  private exampleService = inject(ExampleService);
}

It's a safer, cleaner, and easier-to-read replacement for the traditional constructor-based method that makes it easier for developers to keep their code better organized and consistent. By leveraging the inject function, you reduce boilerplate code, eliminate mistakes, and simplify testing. Your dependencies are simpler to maintain and manage, especially in larger applications where readability and maintainability are crucial to scale and introduce new team members effectively.

Why We Chose the inject Approach

The inject method have to became your choice for clean code because it made the code more readable and maintainable along with more developer-friendly. The method decreases boilerplate code and follows modern Angular development principles.

Implementation

You can use the automatic CLI schematic command for the migration or the following example demonstrates how to use manually inject in an Angular application.

Step 1: Import inject

import { Component, inject } from '@angular/core';
import { ExampleService } from './example.service';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
})
export class ExampleComponent {
  private exampleService = inject(ExampleService);

  exampleMethod() {
   this.exampleService.doSomething();
  }
}

Step 2: Using inject in Services

import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
  export class ExampleService {
  private http = inject(HttpClient);

  doSomething() {
  return this.http.get('/api/example');
  }
}

Conclusion

The new inject function provided by Angular makes your code more maintainable through better dependency management. The inject approach benefits both standalone Angular applications by improving their architectural structure and developer productivity.

You can find additional information about Dependency Injection in Angular through their official documentation.