परिचय: Dependency Injection क्या है और इसकी आवश्यकता क्यों है?
\nसॉफ्टवेयर विकास की दुनिया में, हम अक्सर ऐसी स्थिति का सामना करते हैं जहाँ एक क्लास (या मॉड्यूल) दूसरे पर निर्भर होता है। उदाहरण के लिए, क्लास UserService डेटा सहेजने के लिए क्लास DatabaseService का उपयोग कर सकता है। पारंपरिक दृष्टिकोण DatabaseService का एक इंस्टेंस सीधे UserService के अंदर बनाना है। इससे कोड में मजबूत युग्मन होता है, जो इसके परीक्षण, रखरखाव और विस्तार को जटिल बनाता है।
Dependency Injection (DI) एक डिज़ाइन पैटर्न है जो इस समस्या को हल करता है। क्लास के अंदर निर्भरताएँ बनाने के बजाय, उन्हें बाहर से "इंजेक्ट" किया जाता है। यह नियंत्रण के उलटा (IoC) के सिद्धांत को लागू करता है: क्लास अपनी निर्भरताओं को नियंत्रित नहीं करता, बल्कि बाहरी कोड (कंटेनर या कॉल करने वाला) उन्हें प्रदान करता है।
\nइस लेख में, हम सरल उदाहरणों के साथ TypeScript में Dependency Injection को लागू करने का तरीका समझेंगे। आप जानेंगे कि DI को एक अच्छी प्रथा क्यों माना जाता है और यह स्वच्छ, परीक्षण योग्य कोड लिखने में कैसे मदद करता है।
\n\nसमस्या: DI के बिना कठोर युग्मन
\nआइए एक उदाहरण से शुरू करें जो दिखाता है कि कोड कैसे नहीं लिखना चाहिए। मान लीजिए कि हमारे पास एक एप्लिकेशन है जो उपयोगकर्ताओं को सूचनाएँ भेजता है।
\n// Dependency Injection के बिना
class EmailService {
sendEmail(to: string, message: string): void {
console.log(`ईमेल भेजा जा रहा है ${to} पर: ${message}`);
// ... वास्तविक भेजने की लॉजिक
}
}
class NotificationService {
private emailService: EmailService;
constructor() {
// समस्या: कठोर युग्मन
this.emailService = new EmailService();
}
notifyUser(userEmail: string, message: string): void {
this.emailService.sendEmail(userEmail, message);
}
}
// उपयोग
const notifier = new NotificationService();
notifier.notifyUser('user@example.com', 'Hello!');
इस कोड में, NotificationService EmailService से कठोर रूप से जुड़ा हुआ है। क्या होगा यदि हम SMS या push सूचनाएँ भेजना चाहते हैं? हमें NotificationService का कोड बदलना होगा। इसके अलावा, NotificationService का परीक्षण करना कठिन है - हम वास्तविक EmailService को मॉक ऑब्जेक्ट से प्रतिस्थापित नहीं कर सकते।
समाधान: कंस्ट्रक्टर के माध्यम से निर्भरता इंजेक्शन
\nDI को लागू करने का सबसे सरल और सामान्य तरीका कंस्ट्रक्टर के माध्यम से निर्भरताएँ पास करना है। यह कोड को लचीला और आसानी से परीक्षण योग्य बनाता है।
\nपहले हम अपनी सूचना सेवा के लिए एक इंटरफ़ेस परिभाषित करेंगे। यह एक महत्वपूर्ण कदम है: हम ठोस कार्यान्वयन के बजाय अमूर्तता के स्तर पर प्रोग्रामिंग कर रहे हैं।
\n// किसी भी सूचना सेवा के लिए इंटरफ़ेस परिभाषित करें
interface INotificationService {
send(to: string, message: string): void;
}
// Email के लिए कार्यान्वयन
class EmailService implements INotificationService {
send(to: string, message: string): void {
console.log(`[EMAIL] ${to} पर भेजा गया: ${message}`);
}
}
// SMS के लिए कार्यान्वयन
class SMSService implements INotificationService {
send(to: string, message: string): void {
console.log(`[SMS] ${to} पर भेजा गया: ${message}`);
}
}
// वह क्लास जो DI का उपयोग करता है
class UserNotifier {
private notifier: INotificationService;
// निर्भरता कंस्ट्रक्टर के माध्यम से इंजेक्ट की जाती है
constructor(notifier: INotificationService) {
this.notifier = notifier;
}
notifyUser(userContact: string, message: string): void {
this.notifier.send(userContact, message);
}
}
// उपयोग
const emailNotifier = new UserNotifier(new EmailService());
emailNotifier.notifyUser('alice@example.com', 'आपका ऑर्डर तैयार है!');
const smsNotifier = new UserNotifier(new SMSService());
smsNotifier.notifyUser('+7-999-123-45-67', 'पुष्टिकरण कोड: 1234');
अब UserNotifier यह नहीं जानता कि कौन सा विशेष सेव