Angular Services and Dependency Injection (Angular 21+)

Updated July 4, 2026. Refreshed for Angular 21 and current SEO best practices.

Angular 21 Notes

Use @Injectable({ providedIn: 'root' }) and inject() in standalone components — the modern replacement for constructor injection boilerplate.

This lesson explains Angular services and dependency injection (DI) — how to share logic, API clients, and state across components without prop drilling. Angular’s DI container is a core reason the framework scales in enterprise codebases.

Prerequisites: Lessons 1–4. Estimated time: 40–50 minutes.

1. What Is a Service?

A service is a TypeScript class responsible for a focused capability — fetching users, wrapping localStorage, or encapsulating business rules. Components stay thin; services hold reusable logic.

ng generate service services/greeting --skip-tests
Angular service layer architecture diagram
Photo by Jakub Żerdzicki on Unsplash

2. @Injectable and providedIn: ‘root’

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

@Injectable({ providedIn: 'root' })
export class GreetingService {
  private readonly messages = signal<string[]>([]);

  add(message: string) {
    this.messages.update((list) => [...list, message]);
  }

  all() {
    return this.messages.asReadonly();
  }
}

providedIn: 'root' registers a singleton for the entire app — no NgModule providers array required.

TypeScript injectable service in an Angular project
Photo by Chris Ried on Unsplash

3. Inject Services with inject()

import { Component, inject } from '@angular/core';
import { GreetingService } from '../services/greeting';

@Component({
  selector: 'app-greeting-list',
  standalone: true,
  template: `
    <ul>
      @for (msg of service.all()(); track msg) {
        <li>{{ msg }}</li>
      }
    </ul>
    <button (click)="add()">Add</button>
  `,
})
export class GreetingList {
  protected readonly service = inject(GreetingService);

  add() {
    this.service.add('Hello from DI');
  }
}

4. Testing Services

With Vitest (Angular 21 default), configure TestBed or instantiate services directly when they have no Angular dependencies:

const service = new GreetingService();
service.add('test');
expect(service.all()()).toContain('test');

5. Next Steps

Continue to Lesson 6 — HTTP Client to load data from REST APIs inside services.

Frequently Asked Questions

What is dependency injection in Angular?
A pattern where Angular creates and supplies class dependencies automatically — you declare what you need via constructor or inject().

When should I use a service vs a signal in a component?
Keep UI-only state in the component. Move shared or API-backed logic into services.


Want live Angular or frontend classes? Join Alkademy for instructor-led Angular and frontend courses with hands-on projects.

Leave a Comment