Services & Dependency Injection
📚 What are Services?
Services are classes that handle business logic, data access, and shared functionality.
- Dependency Injection (DI): Angular's powerful pattern for providing dependencies
- Singleton: providedIn: 'root' creates one instance for entire app
- inject() function: Modern way to inject dependencies (v14+)
- Hierarchical Injectors: Component-level providers create separate instances
🎯 Interview Questions
- Q1: What is Dependency Injection?
- A: Design pattern where dependencies are provided rather than created. Angular's DI creates and manages instances.
- Q2: What is the difference between providedIn: 'root' vs component-level providers?
- A: 'root' creates singleton for entire app. Component-level creates new instance per component (and its children).
- Q3: What is inject() function vs constructor injection?
- A: inject() is functional approach (v14+), works outside constructors. Constructor injection is class-based (older approach).
- Q4: What are Injection Tokens?
- A: Used for injecting non-class values like config objects or primitives.
🔧 Live Demo - Shared Service
Counter Service (Singleton)
Count: 0
This value is shared across the entire app!
User Service
- • Alice
- • Bob
- • Charlie
📋 Provider Types
| Provider Type | Description |
|---|---|
| useClass | Provide a different class implementation |
| useValue | Provide a static value |
| useFactory | Provide value from a factory function |
| useExisting | Alias to another provider |
💻 Service Code
import { Injectable, inject, signal } from '@angular/core';
// Singleton Service (providedIn: 'root')
@Injectable({
providedIn: 'root', // Tree-shakable singleton
})
export class CounterService {
private readonly count = signal(0);
// Expose read-only signal
readonly currentCount = this.count.asReadonly();
increment(): void {
this.count.update(v => v + 1);
}
}
// Component using the service
@Component({...})
export class MyComponent {
// Modern inject() function (v14+)
private readonly counterService = inject(CounterService);
// Or constructor injection (older approach)
// constructor(private counterService: CounterService) {}
}
// Injection Token for non-class values
import { InjectionToken } from '@angular/core';
export const API_URL = new InjectionToken<string>('API_URL');
// Providing in app config
export const appConfig = {
providers: [
{ provide: API_URL, useValue: 'https://api.example.com' }
]
};