NestJS — Node.js للمؤسسات

المزوّدات المخصّصة

16 دقيقة الدرس 8 من 48

المزوّدات المخصّصة

الاختصار providers: [UsersService] يغطّي معظم الحالات، لكنّ NestJS يوفّر أربعة تعريفات صريحة للمزوّدات لتحكّم كامل في ما يُحقَن لرمزٍ معيّن. وهذه مفتاح التطبيقات المرنة والقابلة للاختبار والإعداد.

كائن المزوّد الكامل

يمكن كتابة كل مزوّد ككائن برمز provide وإحدى أربع استراتيجيات: useClass أو useValue أو useFactory أو useExisting.

useClass — تبديل التطبيق

اربط رمزًا بصنف، وتستطيع تغيير الصنف المُستخدَم دون لمس المستهلكين. وهذا مثالي لتبديل التطبيقات حسب البيئة:

const loggerProvider = { provide: LoggerService, useClass: process.env.NODE_ENV === 'production' ? ProductionLogger : DevelopmentLogger, }; @Module({ providers: [loggerProvider] }) export class AppModule {}

كل ما يحقن LoggerService يحصل على المُسجّل المناسب للبيئة — دون تغيير كود المستهلك.

useValue — حقن قيمة ثابتة

زوّد قيمة جاهزة: كائن إعدادات أو ثابتًا أو نسخة وهميّة في الاختبارات:

const configProvider = { provide: 'APP_CONFIG', useValue: { apiUrl: 'https://api.example.com', timeout: 5000 }, };
تتألّق useValue في الاختبار. استبدل مزوّدًا حقيقيًا بكائن وهميّ في وحدة الاختبار ولن يدري بقيّة التطبيق — لا استدعاءات شبكة، وحتميّة كاملة.

useFactory — بناؤه ديناميكيًا

حين يحتاج المزوّد إلى حساب أو إلى تبعيات خاصّة لإنشائه، استخدم دالّة مصنع. اذكر تبعياتها في inject وتُمرَّر كوسائط:

const dbProvider = { provide: 'DATABASE_CONNECTION', useFactory: (config: ConfigService) => { return createConnection({ url: config.get('DB_URL') }); }, inject: [ConfigService], // تُحقَن في المصنع };

يمكن أن تكون المصانع async أيضًا — أعِد وعدًا (Promise) وينتظره NestJS قبل اكتمال إقلاع التطبيق.

useExisting — إنشاء اسم بديل

توجّه useExisting رمزًا إلى آخر، فتُنشئ اسمًا بديلًا لـ النسخة نفسها (لا نسخة منها):

const aliasProvider = { provide: 'AliasedLogger', useExisting: LoggerService, // المفرد نفسه، باسمين };
تُعيد useExisting استخدام النسخة القائمة؛ بينما تُنشئ useClass نسخة جديدة. الخلط بينهما يؤدّي إلى نسختين منفصلتين حين توقّعت كائنًا واحدًا مشتركًا — مصدر خفيّ لأخطاء الحالة.

اختيار الأنسب

  • useClass — حين يجب أن يتغيّر التطبيق (حسب البيئة أو الميزة).
  • useValue — للثوابت وكائنات الإعداد ونُسخ الاختبار الوهميّة.
  • useFactory — حين يحتاج الإنشاء إلى منطق أو عمل غير متزامن أو مزوّدات أخرى.
  • useExisting — لكشف مزوّد تحت رمز إضافي.

الخلاصة

تفصل المزوّدات المخصّصة الرمز عن تطبيقه. تُبدّل useClass التطبيقات، وتحقن useValue الثوابت والنُسخ الوهميّة، وتبني useFactory المزوّدات ديناميكيًا (بتبعياتها المحقونة)، وتُنشئ useExisting اسمًا بديلًا لنسخة قائمة. تاليًا نجعل الوحدات نفسها قابلة للإعداد عبر الوحدات الديناميكية ونطاقات المزوّدات.