Services & Dependency Injection
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
providersarray 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.