حاوية حقن التبعيات لجافا سكريبت (Node.js): Awilix

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

حاوية حقن التبعيات لجافا سكريبت (Node.js): Awilix

\n\n

في التطوير الحديث على Node.js، يعد الحفاظ على نقاء البنية وقابلية اختبار الكود أمرًا بالغ الأهمية. أحد الأنماط الرئيسية التي تساعد في ذلك هو حقن التبعيات (DI). لتنفيذ هذا النمط بفعالية في بيئة جافا سكريبت، تم إنشاء مكتبات متخصصة - حاويات حقن التبعيات. في هذه المقالة، سنستعرض بالتفصيل واحدة من أشهر المكتبات وأخفها وزنًا - Awilix.

\n\n

ما هو حقن التبعيات ولماذا نحتاج إلى حاوية؟

\n\n

في النهج التقليدي، يقوم الكائن بإنشاء تبعياته بنفسه (على سبيل المثال، باستخدام عامل التشغيل new). يؤدي هذا إلى ارتباط قوي في الكود، مما يعقد الاختبار والتعديل. يقترح نمط حقن التبعيات تمرير (حقن) التبعيات من الخارج. أما الحاوية فتقوم بأتمتة هذه العملية: فهي تعرف كيفية إنشاء الكائنات وتبعياتها، وتوفر نسخًا جاهزة عند الطلب.

\n\n

Awilix: حاوية DI خفيفة الوزن وقوية

\n\n

Awilix هي مكتبة لـ جافا سكريبت (Node.js) تنفذ نمط عكس التحكم (IoC) باستخدام حاوية. تم كتابتها من الصفر لـ Node.js، وتدعم حل التبعيات غير المتزامن، وأنماط تسجيل مختلفة (فئات، مصانع، قيم)، والكشف التلقائي عن التبعيات عبر المُنشئ.

\n\n

الميزات الرئيسية:

\n
    \n
  • الحقن التلقائي: تقوم الحاوية بتحليل معاملات المُنشئ أو الدالة وحقن التبعيات المطلوبة تلقائيًا.
  • \n
  • دعم عدم التزامن: يمكن أن تكون التبعيات غير متزامنة (مثل الاتصال بقاعدة البيانات)، وتنتظر الحاوية حلها بشكل صحيح.
  • \n
  • أنماط تسجيل متنوعة: يمكنك تسجيل الفئات (asClass)، دوال المصنع (asFunction)، أو القيم الجاهزة (asValue).
  • \n
  • النطاقات (Scopes): يتم دعم دورات حياة مختلفة للكائنات (singleton، transient، scoped).
  • \n
  • النمطية: يمكن تقسيم الحاوية بسهولة إلى وحدات وتسجيل التبعيات في أجزاء مختلفة من التطبيق.
  • \n
\n\n

التثبيت والاستخدام الأساسي

\n\n

يتم تثبيت Awilix عبر npm:

\n\n
npm install awilix
\n\n

لنلقِ نظرة على مثال بسيط. لنفترض أن لدينا خدمة للعمل مع المستخدمين تعتمد على مسجل (logger) ومستودع (repository).

\n\n
const { createContainer, asClass, asFunction, asValue } = require('awilix');\n\n// 1. تعريف التبعيات\nclass Logger {\n    log(message) {\n        console.log(`[LOG]: ${message}`);\n    }\n}\n\nclass UserRepository {\n    constructor({ logger }) {\n        this.logger = logger;\n    }\n\n    findById(id) {\n        this.logger.log(`البحث عن مستخدم بالمعرف: ${id}`);\n        return { id, name: 'John Doe' };\n    }\n}\n\nclass UserService {\n    constructor({ userRepository, logger }) {\n        this.userRepository = userRepository;\n        this.logger = logger;\n    }\n\n    getUser(id) {\n        this.logger.log('طلب في UserService');\n        return this.userRepository.findById(id);\n    }\n}\n\n// 2. إنشاء الحاوية وتسجيل التبعيات\nconst container = createContainer();\n\ncontainer.register({\n    logger: asClass(Logger).singleton(),\n    userRepository: asClass(UserRepository).singleton(),\n    userService: asClass(UserService).singleton()\n});\n\n// 3. استخدام الحاوية للحصول على الخدمة\nconst userService = container.resolve('userService');\nconst user = userService.getUser(1);\nconsole.log(user);\n// الإخراج:\n// [LOG]: طلب في UserService\n// [LOG]: البحث عن مستخدم بالمعرف: 1\n// { id: 1, name: 'John Doe' }\n<                    

توصيات