Dependency Injection System in Angular 18

Introduction

Angular 18 has introduced a variety of exciting new features and improvements. One of the standout enhancements is the updated Dependency Injection (DI) system. DI is a fundamental concept in Angular, crucial for building scalable and maintainable applications by managing the dependencies of components and services. Let's dive into the new DI features in Angular 18 and walk through a practical example to see them in action.

What’s New in Angular 18's DI System?

  1. Improved Tree-Shakability: Angular 18 enhances tree-shakability, ensuring that only the necessary code gets included in the final bundle. This leads to smaller, more efficient applications.
  2. Injection Contexts: New injection contexts allow developers to specify and manage different contexts for dependency injection, giving more control and flexibility.
  3. Provider Scopes: The new provider scopes feature offers more granular control over the lifecycle of dependencies, improving performance and resource management.
  4. Simplified Provider Syntax: Angular 18 introduces a simplified syntax for declaring providers, making the code more readable and maintainable.

Example. Using Angular 18's New Dependency Injection Features

Let's build a simple Angular 18 application that demonstrates these new DI features. We'll create a service, inject it into a component, and explore the new DI capabilities.

Step 1. Setting Up the Angular 18 Project

First, set up a new Angular 18 project using the Angular CLI

ng new angular18-di-demo
cd angular18-di-demo

Step 2. Creating a Service

We'll create a new service to provide some data to our component. Run the following command to generate the service:

ng generate service data

Open data.service.ts and implement the service like this:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class DataService {
  private data = ['Angular 18', 'Dependency Injection', 'New Features'];

  constructor() {}

  getData(): string[] {
    return this.data;
  }
}

Here, the @Injectable decorator with providedIn: 'root' makes this service available throughout the application.

Step 3. Creating a Component

Next, we'll create a component to display the data provided by DataService. Run the following command.

ng generate component data-display

Open data-display.component.ts and inject DataService.

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-data-display',
  templateUrl: './data-display.component.html',
  styleUrls: ['./data-display.component.css']
})
export class DataDisplayComponent implements OnInit {
  data: string[] = [];

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.data = this.dataService.getData();
  }
}

In this component, we inject DataService in the constructor and use it to fetch data in the ngOnInit lifecycle hook.

Step 4. Displaying the Data

Open data-display.component.html and update the template to display the data:

<div>
  <h2>Data from DataService</h2>
  <ul>
    <li *ngFor="let item of data">{{ item }}</li>
  </ul>
</div>

Step 5. Using the Component

Include the DataDisplayComponent in your main application component. Open app.component.html and add the following.

<app-data-display></app-data-display>

Step 6. Running the Application

Run the application using the Angular CLI.

ng serve

Navigate to http://localhost:4200 in your browser. You should see the data displayed from DataService.

Summary

In this article, we've explored the new Dependency Injection features in Angular 18. By creating a simple service and component, we've seen how to use DI in Angular 18. The enhancements in the DI system, such as improved tree-shakability, injection contexts, provider scopes, and simplified syntax, make managing dependencies in Angular applications easier and more efficient. These features will help you maintain a clean and scalable codebase as you build more complex applications.


Similar Articles