Angular में Providers और Injection Tokens Dependency Injection (DI) system का advanced और powerful हिस्सा हैं। Providers Angular को बताते हैं कि किसी dependency को कैसे create करना है, और Injection Tokens उन cases को handle करते हैं जहाँ class-based injection possible नहीं होती।
इस chapter में हम Providers और Injection Tokens को beginner से advanced level तक deep में समझेंगे, real-world examples के साथ।
Provider क्या होता है
Provider Angular को यह information देता है कि:
- कौन-सी dependency provide करनी है
- उसका instance कैसे create होगा
- कौन-सा value या class inject होगी
Simple provider:
providers: [UserService]
यह Angular को बताता है कि UserService को create और inject किया जा सकता है।
Provider कैसे काम करता है
Provider internally यह mapping बनाता है:
Token → Value / Class / Factory
जब भी token inject किया जाता है, injector provider की help से value resolve करता है।
Class Provider (Default)
सबसे common provider type।
providers: [AuthService]
Equivalent explicit form:
providers: [
{ provide: AuthService, useClass: AuthService }
]
यह approach तब use होती है जब class ही token और implementation दोनों हो।
useClass Provider
Alternative implementation inject करने के लिए।
providers: [
{ provide: AuthService, useClass: MockAuthService }
]
Use cases:
- Testing
- Feature-based behavior
- Platform-specific logic
Consumer को change करने की जरूरत नहीं होती।
useValue Provider
Static values या constants provide करने के लिए।
providers: [
{ provide: 'APP_VERSION', useValue: '1.0.0' }
]
Inject करना:
constructor(@Inject('APP_VERSION') version: string) {}
Config values के लिए useful है, लेकिन string tokens recommended नहीं हैं।
InjectionToken क्या है
InjectionToken एक strongly-typed token है जो non-class dependencies के लिए use होता है।
export const API_URL = new InjectionToken<string>('API_URL');
यह string tokens से ज्यादा safe और maintainable है।
InjectionToken Provide करना
providers: [
{ provide: API_URL, useValue: 'https://api.example.com' }
]
Inject करना:
constructor(@Inject(API_URL) private apiUrl: string) {}
यह pattern enterprise configuration में standard है।
useFactory Provider
Dynamic logic से dependency create करने के लिए।
providers: [
{
provide: LoggerService,
useFactory: () => new LoggerService(true)
}
]
Dependencies के साथ:
providers: [
{
provide: ApiService,
useFactory: (config: AppConfig) => new ApiService(config.url),
deps: [AppConfig]
}
]
यह runtime decision-making के लिए powerful approach है।
Factory + InjectionToken Pattern
Complex configuration के लिए common pattern।
export const APP_CONFIG = new InjectionToken<AppConfig>('APP_CONFIG');
providers: [
{
provide: APP_CONFIG,
useFactory: loadConfig
}
]
यह scalable और testable architecture बनाता है।
Multi Providers
Multiple values को same token के साथ inject करने के लिए।
export const HOOKS = new InjectionToken<Function[]>('HOOKS');
providers: [
{ provide: HOOKS, useValue: hookA, multi: true },
{ provide: HOOKS, useValue: hookB, multi: true }
]
Inject करना:
constructor(@Inject(HOOKS) private hooks: Function[]) {}
Use cases:
- Plugin systems
- Event pipelines
- Interceptors-like patterns
Provider Scope
Providers different levels पर register हो सकते हैं:
- Root level
- Module level
- Component level
Scope decide करता है:
- Instance sharing
- Lifecycle
- State isolation
providedIn vs providers Array
Modern approach:
@Injectable({ providedIn: 'root' })
Legacy / scoped approach:
providers: [SomeService]
providedIn:
- Tree-shakable
- Cleaner
- Recommended
providers:
- Scoped services
- Override behavior
Overriding Providers
Child component parent provider override कर सकता है।
@Component({
providers: [
{ provide: LoggerService, useClass: DebugLogger }
]
})
यह testing और feature isolation में useful है।
Optional Providers
Optional dependency inject करना:
constructor(@Optional() private config?: AppConfig) {}
Provider missing होने पर error नहीं आएगा।
Circular Provider Issues
गलत design से circular dependency बन सकती है।
ServiceA → ServiceB
ServiceB → ServiceA
Solution:
- Shared abstraction
- Factory-based injection
- Refactor responsibilities
Providers in Standalone APIs
Standalone components में providers directly define हो सकते हैं।
@Component({
standalone: true,
providers: [AuthService]
})
export class LoginComponent {}
Modern Angular apps में यह common pattern है।
Best Practices
- String tokens avoid करें
- InjectionToken prefer करें
- providedIn use करें
- Multi providers सोच-समझकर use करें
- Providers override carefully करें
Real-World Use Cases
Providers और Injection Tokens heavily used होते हैं:
- Environment configuration
- Feature flags
- Plugin architectures
- API abstraction layers
Angular Providers & Injection Tokens DI system को flexible और enterprise-ready बनाते हैं। इस chapter के बाद आप complex dependency graphs और configuration-driven applications confidently build कर सकते हैं। अगले chapter में हम Angular Advanced DI concepts explore करेंगे, जहाँ hierarchical resolution, custom injectors और edge cases cover होंगे।
