21. فهم حقن التبعية (DI)
حقن التبعية (DI) هو نمط تصميم أساسي في Angular. يسمح لفئة (المُعتمد) بتلقي تبعياتها (الكائنات الأخرى التي تحتاجها لأداء وظيفتها) من مصدر خارجي، بدلاً من إنشائها بنفسها.
لماذا نستخدم DI؟
- قابلية إعادة الاستخدام (Reusability): يمكن إعادة استخدام الخدمات عبر مكونات مختلفة.
- قابلية الاختبار (Testability): يسهل تبديل التبعيات الحقيقية بتطبيقات وهمية (mock implementations) أثناء الاختبار.
- سهولة الصيانة (Maintainability): يفصل المكونات عن تبعياتها، مما يقلل التعقيد.
الأجزاء الثلاثة لـ DI
- المستهلك/المُعتمد (The Consumer/Dependent): المكون أو الخدمة التي تحتاج إلى التبعية (على سبيل المثال، يحتاج
ProductComponentإلىProductService). - التبعية (The Dependency): الفئة التي توفر الوظيفة المطلوبة (على سبيل المثال،
ProductService). - الحاقن (The Injector): آلية Angular المدمجة التي تنشئ وتدير مثيلات التبعية وتحقنها في المستهلك.
كيف يتعامل Angular مع الحقن
يحافظ حاقن Angular على خريطة من الرموز (tokens) (عادةً نوع الفئة) للمُزودين (providers) (وصفات لإنشاء المثيل).
عندما يطلب مكون تبعية عبر مُنشئه (constructor)، يبحث Angular عن مُزود مطابق في شجرة الحقن الخاصة به (بدءاً من مستوى المكون، مروراً بالوحدة، وأخيراً الجذر).
مثال على طلب تبعية:
typescript import { LoggerService } from './logger.service';
// يقرأ Angular معلمة المُنشئ ويحاول تلبية التبعية export class MyComponent { constructor(private logger: LoggerService) { // يتم توفير مثيل المُسجِّل بواسطة حاقن Angular this.logger.log('Component initialized.'); } }