Services & DI
Singleton Pattern in Angular
Ek Hi Instance, Sabke Liye
💡 Singleton service ek company ka SHARED database jaisa hai — sab departments (components) SAME database access karte hain, har department apna alag database nahi banata — consistency guarantee hoti hai.
providedIn: 'root' wala service ek TRUE SINGLETON hai — poore application mein SIRF EK instance banता hai, chahe kितne bhi components use karein. Ye state SHARING ke liye perfect hai — jaise ek shopping cart service jiski state sab components mein consistent honi chahiye.
@Injectable({ providedIn: 'root' })
export class CartService {
private items: any[] = [];
addItem(item: any) {
this.items.push(item);
}
getItemCount() {
return this.items.length;
}
}
// Component A mein add karo:
// this.cartService.addItem(product);
// Component B mein (COMPLETELY different part of app) count dekho:
// this.cartService.getItemCount(); — SAME data, kyunki singleton hai!🔒
Singleton service ek company ka SHARED database jaisa hai — sab departments (components) SAME database access karte hain, har department apna alag database nahi banata — consistency guarantee hoti hai.
1 / 6
⚡ Quick Recap
- providedIn: 'root' = true singleton, poore app mein ek instance
- State sharing/consistency ke liye perfect (jaise shopping cart)
- Simple state management approach — bade apps NgRx/Signals bhi use karte hain
On this page (2 subtopics)
Agar EK service ko root-level (providedIn: 'root') AUR component-level (providers: [...]) DONO jagah declare kar do, component-level WINS — accidentally do alag instances ban jaate hain, jo confusing bugs deta hai.
@Injectable({ providedIn: 'root' })
export class CounterService {
count = 0;
}
@Component({
selector: 'app-child',
providers: [CounterService] // OOPS — naya, ALAG instance banega yaha
})
export class ChildComponent { }
// ChildComponent ka CounterService, root-level singleton se DIFFERENT hai!Common Mistake: Ye ek subtle, common bug hai — agar service ko GENUINELY singleton hona chahiye (state share karna hai), USE component providers[] mein DUBARA list mat karo, sirf root-level @Injectable configuration par bharosa karo.
Singleton services ka state TESTS ke beech "leak" ho sakta hai (agar properly reset na kiya jaaye) — Angular testing utilities (TestBed) har test ke liye FRESH injector create karte hain, is problem ko avoid karne ke liye.
// Test file mein:
beforeEach(() => {
TestBed.configureTestingModule({
providers: [CartService]
});
// Har test ko apna FRESH CartService instance milta hai
});Tip: TestBed Angular ka testing utility hai jo automatically dependency injection ko test-friendly banata hai — real singleton behavior production mein hai, lekin tests isolated rehte hain, ek doosre ke state se affect nahi hote.