JavaScript (Node.js) के लिए Dependency Injection कंटेनर — Awilix
Node.js पर आधुनिक डेवलपमेंट में, कोड की आर्किटेक्चर की सफाई और परीक्षण क्षमता प्राथमिकता बन गई है। इन लक्ष्यों को प्राप्त करने के लिए प्रमुख उपकरणों में से एक है डिपेंडेंसी इंजेक्शन (Dependency Injection, DI)। Awilix लाइब्रेरी JavaScript और TypeScript के लिए एक शक्तिशाली, उच्च-प्रदर्शन और लचीला DI-कंटेनर प्रदान करती है, जो Node.js पर सर्वर-साइड एप्लिकेशन के लिए आदर्श है। इस लेख में, हम विस्तार से समझेंगे कि डिपेंडेंसी प्रबंधन, मॉड्यूलरिटी में सुधार और परीक्षण को सरल बनाने के लिए Awilix का उपयोग कैसे करें।
Dependency Injection क्या है और कंटेनर की आवश्यकता क्यों है?
Dependency Injection एक डिज़ाइन पैटर्न है जिसमें कोई ऑब्जेक्ट अपनी डिपेंडेंसी बाहर से प्राप्त करता है, न कि उन्हें स्वयं बनाता है। यह Inversion of Control (IoC) सिद्धांत को लागू करता है। कंटेनर एक उपकरण है जो इन डिपेंडेंसी को बनाने और प्रदान करने की प्रक्रिया को स्वचालित करता है। क्लासेज़ के इंस्टेंस मैन्युअल रूप से बनाने और उन्हें एक-दूसरे को पास करने के बजाय, आप कंटेनर में बिल्ड नियमों का वर्णन करते हैं, और यह स्वयं सभी डिपेंडेंसी श्रृंखलाओं को हल करता है।
DI-कंटेनर का उपयोग करने के मुख्य लाभ:
- कोड युग्मन में कमी: मॉड्यूल विशिष्ट कार्यान्वयन के बजाय अमूर्तता पर निर्भर करते हैं।
- परीक्षण को सरल बनाना: यूनिट-टेस्ट के दौरान वास्तविक सेवाओं को मॉक (mock) से बदलना आसान है।
- केंद्रीकृत प्रबंधन: सभी डिपेंडेंसी कॉन्फ़िगरेशन एक ही स्थान पर होती है, जिससे रिफैक्टरिंग आसान हो जाती है।
- जीवनचक्र प्रबंधन: कंटेनर नियंत्रित कर सकता है कि कोई ऑब्जेक्ट कितने समय तक जीवित रहता है — पूरे एप्लिकेशन के लिए एक इंस्टेंस (सिंगलटन) या प्रत्येक अनुरोध पर नया।
Awilix की स्थापना
आरंभ करने के लिए, npm के माध्यम से लाइब्रेरी स्थापित करें:
npm install awilixAwilix की कोई बाहरी निर्भरता नहीं है और यह CommonJS और ESM मॉड्यूल दोनों के साथ काम करता है।
Awilix की मुख्य अवधारणाएँ
Awilix कई प्रमुख अवधारणाओं के आसपास बनाया गया है:
- Container (कंटेनर): मुख्य ऑब्जेक्ट जो डिपेंडेंसी को संग्रहीत और प्रदान करता है।
- Registration (पंजीकरण): नाम (टोकन) को फ़ैक्टरी, क्लास या मान से जोड़ने की प्रक्रिया।
- Resolver (रिज़ॉल्वर): ऑब्जेक्ट जो यह निर्धारित करता है कि डिपेंडेंसी कैसे बनाई या प्राप्त की जाए। उदाहरण के लिए,
asClass(),asFunction(),asValue()। - Lifetime (जीवनकाल): यह निर्दिष्ट करता है कि ऑब्जेक्ट कितनी बार बनाया जाएगा:
ScopedLifeTime(प्रति स्कोप एक बार),SingletonLifeTime(पूरे समय में एक बार) याTransientLifeTime(हर बार नया)।
उपयोग का उदाहरण: उपयोगकर्ताओं के साथ काम करने के लिए सेवा
एक सरल उदाहरण पर विचार करें। मान लीजिए कि हमारे पास एक डेटाबेस, एक उपयोगकर्ता रिपॉजिटरी और बिज़नेस लॉजिक के लिए एक सेवा है।
1. क्लासेज़ को परिभाषित करें
// database.jsclass Database { constructor() { this.connection = 'Connected to DB'; } query(sql) { return `Result for: ${sql}`; }}
// userRepository.jsclass UserRepository { constructor({ database }) { this.db = database; } findById(id) { return this.db.query(`SELECT * FROM users WHERE id = ${id}`); }}
// userService.jsclass UserService { constructor({ userRepository }) { this.repo = userRepository; } getUser(id) { return this.repo.findById(id); }}कंस्ट्रक्टर पर ध्यान दें: वे डिपेंडेंसी के साथ एक ऑब्जेक्ट स्वीकार करते हैं। Awilix के लिए यह मानक अभ्यास है।
2. कंटेनर को कॉन्फ़िगर करें
const { createContainer, asClass, asValue, Lifetime } = require('awilix');
const container = createContainer();
// पंजीकरण करें