| وجه المقارنة المعمارية | حقن الأصناف التقليدية (Class-based DI) | حقن القيم عبر InjectionToken (Non-class DI) |
|---|---|---|
| نوع الاعتماد المحقون | كلاسات برمجية صريحة تمتلك مُنشئ ومMethods جاهزة | قيم بدائية، كائنات إعدادات، إعدادات بيئة العمل (`Environment Configs`)، أو واجهات مجردة |
| طريقة التعرف وقت التشغيل | يعتمد أنگولر مباشرة على نوع الصنف (`Class Type`) كمعرف فريد للحقن | يتطلب إنشاء مفتاح رمزي فريد (`InjectionToken`) لتعريف وتوجيه القيمة بدقة |
| المرونة في التغيير | مرتبط ببنية الصنف المحدد وثوابته الداخلية | مرن للغاية، يتيح لك تغيير القيمة أو كائن الإعدادات دون تعديل بنية المكونات المستهلكة |
لا يقتصر حقن الاعتماديات على الأصناف (Classes) والخدمات البرمجية فحسب، بل قد تحتاج أحياناً إلى حقن قيم بدائية مثل النصوص، الثوابت، كائنات الإعدادات (Config Objects)، أو الواجهات (Interfaces) التي لا تمتلك تمثيلاً برمجياً كصنف حقيقي وقت التشغيل. هنا يبرز دور InjectionToken كأداة معمارية قوية لربط وتوفير هذه القيم غير النمطية بأمان داخل شجرة الحقن.
بما أن لغة الجافاسكريبت تفقد معلومات الواجهات (Interfaces) وقت التشغيل (Runtime), فإن InjectionToken يوفر معرفاً فريداً وثابتاً يمكن أنگولر من معرفة القيمة المطلوبة وحقنها في المكان الصحيح بكل دقة.
يُستخدم InjectionToken على نطاق واسع لتمرير إعدادات الخادم (API Base URL)، خيارات الميزات المفعلة، أو مفاتيح الطرف الثالث، مما يسهل عملية اختبار المكونات عبر تمرير قيم وهمية (Mock Values) بكل سهولة.
| 1 | import { InjectionToken } from '@angular/core'; |
| 2 | |
| 3 | // تعريف واجهة كائن الإعدادات |
| 4 | export interface ApiConfig { |
| 5 | baseUrl: string; |
| 6 | timeout: number; |
| 7 | } |
| 8 | |
| 9 | // إنشاء InjectionToken مع قيمة افتراضية عبر providedIn أو عبر الـ Providers |
| 10 | export const API_CONFIG_TOKEN = new InjectionToken<ApiConfig>('api.config.token', { |
| 11 | providedIn: 'root', |
| 12 | factory: () => ({ |
| 13 | baseUrl: 'https://api.enterprise-angular.22.1.com', |
| 14 | timeout: 5000 |
| 15 | }) |
| 16 | }); |
| 1 | import { Component, inject } from '@angular/core'; |
| 2 | import { CommonModule } from '@angular/common'; |
| 3 | import { API_CONFIG_TOKEN } from './api-config.token'; |
| 4 | |
| 5 | @Component({ |
| 6 | selector: 'app-token-demo', |
| 7 | standalone: true, |
| 8 | imports: [CommonModule], |
| 9 | template: ` |
| 10 | <div class="token-container"> |
| 11 | <h3>لوحة استخدام InjectionToken للقيم غير النمطية</h3> |
| 12 | <div class="config-box"> |
| 13 | <p><strong>رابط الخادم الأساسي:</strong> {{ config.baseUrl }}</p> |
| 14 | <p><strong>مدة الانتظار القصوى:</strong> {{ config.timeout }} ms</p> |
| 15 | </div> |
| 16 | </div> |
| 17 | `, |
| 18 | styles: [` |
| 19 | .token-container { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; border: 1px solid #1e293b; } |
| 20 | .config-box { background: #1e293b; padding: 16px; border-radius: 8px; border: 1px solid #334155; color: #38bdf8; font-weight: bold; } |
| 21 | `] |
| 22 | }) |
| 23 | export class TokenDemoComponent { |
| 24 | // حقن القيمة غير النمطية باستخدام InjectionToken ودالة inject الحديثة |
| 25 | readonly config = inject(API_CONFIG_TOKEN); |
| 26 | } |
⚠️ تحذير
احذر من تمرير قيم عشوائية بدون تحديد نوع بيانات واضح (Type Safety)! احرص دائماً على ربط InjectionToken بواجهة محددة (Interface) لضمان الحفاظ على أمان الأنواع البرمجية ومنع حدوث أخطاء وقت الترجمة أو التشغيل.