Services & Dependency Injection

🅰️ Angular Lesson 7 Intermediate

Services handle application business logic, while Dependency Injection (DI) manages how components receive these services, promoting clean, testable code.

1 Singleton patterns and local instances

Angular's dependency injection system uses a tree structure:

  • providedIn: 'root': Registers the service as a global singleton, meaning a single shared instance is used across the entire application.
  • Component-level providers: Registering a service in a component's providers array creates a new, local instance for that component and its children.
2 Creating and Injecting services

Let's check how a data service is written and injected:

TypeScript — Log Service
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root' // singleton registration
})
export class LogService {
  private logs: string[] = [];

  addLog(msg: string) {
    this.logs.push(msg);
    console.log('[LOG SERVICE]:', msg);
  }

  getLogs() {
    return this.logs;
  }
}

To use the service, inject it through a component's class constructor:

TypeScript — Injecting Service
import { Component, OnInit } from '@angular/core';
import { LogService } from './log.service';

@Component({
  selector: 'app-dashboard',
  template: `

Dashboard loaded. See console logs.

` }) export class DashboardComponent implements OnInit { // Service injection via constructor parameter constructor(private logger: LogService) {} ngOnInit() { this.logger.addLog('DashboardComponent initialized successfully.'); } }
3 Code Challenge
Challenge: Write a new service called UserService that stores a private list of users. Expose methods to fetch and add users, and inject it into a list component.