في هندسة البرمجيات، يعد **حقن التبعية** (بالإنجليزية: dependency injection)‏ تقنية يتلقى فيها كائن كائنات أخرى يعتمد عليها. تسمى هذه الكائنات الأخرى التبعيات.

في العلاقة النموذجية «باستخدام» يسمى الكائن المتلقي عميل (بالإنجليزية: Client)‏ ويسمى الكائن الذي تم تمريره (أي **تم حقنه**) خدمة (بالإنجليزية: Service)‏. يمكن أن يكون الكود الذي ينقل الخدمة إلى العميل أنواعًا كثيرة ويسمى الحاقن. بدلاً من تحديد العميل للخدمة التي سيستخدمها، يخبر الحاقن العميل بالخدمة التي سيستخدمها. تشير «الحقن» إلى تمرير التبعية (خدمة) إلى الكائن (العميل) الذي قد يستخدمها.

الخدمة تصبح جزءاً من حالة العميل. يعد تمرير الخدمة إلى العميل، بدلاً من السماح للعميل ببناء الخدمة أو العثور عليها، شرطاً أساسياً للنمط.

النية من حقن التبعية هو تحقيق فصل الاهتمامات الخاصة بالبناء واستخدام الكائنات. يمكن أن يؤدي ذلك إلى زيادة إمكانية القراءة وإعادة استخدام الكود.

حقن التبعية هو شكل من أشكال التقنية الأوسع لعكس التحكم. لا يجب على العميل الذي يريد استدعاء بعض الخدمات معرفة كيفية إنشاء هذه الخدمات. بدلاً من ذلك، يفوض العميل مسؤولية توفير خدماته للكود الخارجي (الحاقن). لا يُسمح للعميل باستدعاء كود الحاقن ؛ الحاقن هو الذي يبني الخدمات. ثم يقوم الحاقن بحقن (تمرير) الخدمات في العميل التي قد تكون موجودة بالفعل أو قد يتم بناؤها بواسطة الحاقن. ثم يستخدم العميل الخدمات. هذا يعني أن العميل لا يحتاج إلى معرفة الحاقن، وكيفية إنشاء الخدمات، أو حتى الخدمات الفعلية التي يستخدمها. يحتاج العميل فقط إلى معرفة الواجهات الجوهرية للخدمات لأن هذه تحدد كيفية استخدام العميل للخدمات. وهذا يفصل مسؤولية «الاستخدام» (بالإنجليزية: "use")‏ عن مسؤولية «البناء» (بالإنجليزية: "construction")‏.

نوايا
-----

حقن التبعية يحل مشاكل مثل:

* كيف يمكن أن يكون التطبيق أو الصنف مستقل عن كيفية إنشاء كائناته؟
* كيف يمكن تحديد طريقة إنشاء الكائنات في ملفات تكوين منفصلة؟
* كيف يمكن لتطبيق دعم تكوينات مختلفة؟

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

إذا كانت هناك حاجة إلى كائنات أخرى، ويجعل من الصعب اختبار الصنف لأنه لا يمكن استبدال الكائنات الحقيقية بكائنات وهمية.

لم يعد الصنف مسؤول عن إنشاء الكائنات التي يتطلبها، ولا يتعين عليه تفويض إنشاء مثيل لكائن مصنع كما هو الحال في نمط تصميم.  

انظر أيضًا صنف UML ومخطط التسلسل أدناه.

نظرة عامة
---------

حقن التبعية يفصل إنشاء تبعيات العميل عن سلوك العميل، والذي يسمح لتصاميم البرنامج أن تكون مقترنة بشكل متساهل ومتابعة انعكاس التبعية ومبادئ المسؤولية الواحدة. يتناقض بشكل مباشر مع نمط محدد مواقع الخدمة، والذي يسمح للعملاء بمعرفة النظام الذي يستخدمونه للعثور على التبعيات. الحقن، الوحدة الأساسية لحقن التبعية، ليست آلية جديدة أو مخصصة. يعمل بنفس الطريقة التي يعمل بها «تمرير المعلمة».

بالإشارة إلى «تمرير المعلمة» حيث أن الحقن يحمل ضمناً إضافياً أنه يتم القيام به لعزل العميل عن التفاصيل.

إن الحقن يتعلق أيضًا بما يتحكم في المرور (وليس العميل) مطلقًا وهو مستقل عن كيفية تحقيق التمرير، سواء عن طريق تمرير مرجع أو قيمة يشمل حقن التبعية أربعة أدوار:

* كائن (ات) **خدمة** **service** لاستخدامها.
* كائن **العميل**  الذي يعتمد على الخدمة (الخدمات) التي يستخدمها.
* الواجهات التي تحدد كيفية استخدام العميل للخدمات.
* **الحاقن**، وهو المسؤول عن إنشاء الخدمات وحقنها في العميل.

كمثال:

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

أي كائن يمكن استخدامه يمكن اعتباره **خدمة**. يمكن اعتبار أي كائن يستخدم كائنات أخرى **عميلاً** **.** *لا علاقة للأسماء بماهية الكائنات وكل شيء يتعلق بالدور الذي تلعبه الكائنات في أي حقن***.**

**الواجهات** هي الأنواع التي يتوقع العميل تبعياتها. المشكلة هي ما يجعلها متاحة. قد تكون بالفعل أنواع من الواجهة يتم تنفيذها بواسطة الخدمات ولكن قد تكون أيضًا أصناف مجردة أو حتى الخدمات نفسها على الرغم من أن هذا الأخير قد ينتهك DIP ويضحي بفك الارتباط الديناميكي الذي يتيح الاختبار. يتطلب فقط ألا يعرف العميل هويته وبالتالي لا يتعامل معه على أنه ملموس، على سبيل المثال من خلال إنشائها أو توسيعها.

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

يمكن تطبيق حقن التبعية كنظام، واحد يطلب من جميع الكائنات صنف البناء والسلوك. يمكن أن يؤدي الاعتماد على إطار عمل حقن التبعية بالقيام بالإنشاء إلى حظر استخدام الكلمة المفتاحية "new"، أو بشكل أقل صرامة، السماح بالبناء المباشر لعناصر القيمة فقط.

### التصنيف

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

### أطر حقن التبعية

أطر التطبيقات مثل CDI وتنفيذها مثل Weld وسبرينغ و Guice واطار عمل بلاي و Salta و Glassfish HK2 و Dagger وإطار التوسعة المدار (MEF) تدعم حقن التبعية ولكن غير الزامية للقيام بحقن التبعية.

### مزايا

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

### سلبيات

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

هيكل (بناء)
-----------

### مخطط الصنف UML ومخطط التتابع

  

 نموذج لصنف UML ومخطط تسلسلي لنمط تصميم حقن التبعية. 
فيUML الرسم التخطيطي لصنف أعلاه، لا يقوم صنف `Client` الذي يتطلب كائنات `ServiceA` و `ServiceB` بإنشاء صنفي`ServiceA1` و `ServiceB1` مباشرة. بدلاً من ذلك، يقوم صنف `Injector` بإنشاء الكائنات وحقنها في `Client`، مما يجعل `Client` مستقلًا عن كيفية إنشاء الكائنات (أي الأصناف الملموسة التي يتم إنشاء مثيل لها). يوضح الرسم التخطيطي لتسلسل UML تفاعلات وقت التشغيل يقوم كائن `Injector` بإنشاء كائنات `ServiceA1` و `ServiceB1`. بعد ذلك، يقوم `Injector` بإنشاء كائن `Client` وإدخال كائنات `ServiceA1` و `ServiceB1`.

أمثلة
-----

**بدون حقن التبعية**

في مثال جافا التالي، يحتوي صنف على خدمة متغير عضو تمت تهيئته بواسطة مُنشئ.

يتحكم العميل في تنفيذ الخدمة المستخدمة ويتحكم في بنائها. في هذه الحالة، يُقال أن العميل لديه تبعية ذات كود صلب على. (بالإنجليزية: ExampleService)‏

```
// An example without dependency injection
public class Client {
 // Internal reference to the service used by this client
 private ExampleService service;

 // Constructor
 Client() {
 // Specify a specific implementation in the constructor instead of using dependency injection
 service = new ExampleService();
 }

 // Method within this client that uses the services
 public String greet() {
 return "Hello "+ service.getName();
 }
}

```
 يعتبر حقنالتبعية تقنية بديلة لتهيئة متغير العضو بدلاً من إنشاء كائن خدمة بشكل صريح كما هو موضح أعلاه. يمكننا تعديل هذا المثال

باستخدام التقنيات المختلفة الموضحة والموضحة في الأقسام الفرعية أدناه..

### أنواع حقن التبعية

هناك ثلاث طرق على الأقل يمكن لكائن العميل تلقي مرجع لوحدة خارجية:

*حقن المنشئ*
يتم توفير التبعيات من خلال مُنشئ صنف العميل..
*حقن المعيّن*
يكشف العميل عن طريقة الضبط التي يستخدمها الحاقن لحقن التبعية..
*حقن الواجهة*
توفر واجهة التبعية طريقة حاقن تضخ التبعية في أي عميل يتم تمريره إليها. يجب على العملاء تنفيذ واجهة تكشف عن طريقة تعيين يقبل التبعية.
#### أنواع أخرى

من الممكن أن يكون لأطر حقن التبعية أنواع أخرى من *الحقن* بخلاف تلك المذكورة أعلاه. قد تستخدم أطر الاختبار أيضًا أنواعًا أخرى. بعض أطر الاختبار الحديثة لا تتطلب حتى أن يقبل العملاء بنشاط حقن التبعية وبالتالي جعل الكود القديم قابل للاختبار. على وجه الخصوص، في لغة جافا، من الممكن استخدام الانعكاس لجعل السمات الخاصة عامة عند الاختبار وبالتالي قبول الحقن عن طريق التعيين.

لا تقدم بعض محاولات عكس التحكم الإزالة الكاملة للتبعية، ولكن بدلاً من ذلك ببساطة استبدال أحد أشكال التبعية بأخرى. كقاعدة عامة، إذا لم يتمكن المبرمج من النظر إلى شيء سوى كود العميل والإخبار عن إطار العمل المستخدم، عندئذٍ يكون لدى العميل اعتماد مرتبط بالكود الصلب على الإطار.

#### حقن المنشئ

تتطلب هذه الطريقة من العميل توفير معلمة في مُنشئ للتبعية.

```
// Constructor
Client(Service service) {
 // Save the reference to the passed-in service inside this client
 this.service = service;
}

```

#### حقن المعيّن

تتطلب هذه الطريقة من العميل توفير طريقة ضبط للتبعية.

```
// Setter method
public void setService(Service service) {
 // Save the reference to the passed-in service inside this client.
 this.service = service;
}

```

#### حقن الواجهة

ببساطة العميل هو الذي ينشر واجهة الدور لطرق تعيين تبعيات العميل. يمكن استخدامه لتحديد الطريقة التي يجب أن يتحدث بها الحاقن مع العميل عند حقن التبعيات.

```
// Service setter interface.
public interface ServiceSetter {
 public void setService(Service service);
}

// Client class
public class Client implements ServiceSetter {
 // Internal reference to the service used by this client.
 private Service service;

 // Set the service that this client is to use.
 @Override
 public void setService(Service service) {
 this.service = service;
 }
}

```

#### مقارنة حقن المنشئ

يُفضل عند إنشاء جميع التبعيات أولاً لأنه يمكن استخدامها لضمان أن يكون كائن العميل دائمًا في حالة صالحة، على العكس من ذلك هو أن تكون بعض مراجع التبعية الخاصة به خالية (لم يتم تعيينها). ومع ذلك، من تلقاء نفسها، تفتقر إلى المرونة لتغيير تبعياتها في وقت لاحق. يمكن أن تكون هذه خطوة أولى نحو جعل العميل غير قابل للتغيير وبالتالي خيط آمن.

```
// Constructor
Client(Service service, Service otherService) {
 if (service == null) {
 throw new InvalidParameterException("service must not be null");
 }
 if (otherService == null) {
 throw new InvalidParameterException("otherService must not be null");
 }

 // Save the service references inside this client
 this.service = service;
 this.otherService = otherService;
}

```

#### مقارنة حقن المعيّن (الضبط)

يتطلب من العميل توفير طريقة ضبط لكل تبعية. وهذا يعطي حرية التلاعببحالة المراجع التبعية في أي وقت. يوفر هذا المرونة، ولكن إذا كان هناك أكثر من تبعية واحدة يجب حقنها، فمن الصعب على العميل التأكد من حقن جميع التبعيات قبل أن يتم توفير العميل للاستخدام.

```
// Set the service to be used by this client
public void setService(Service service) {
 if (service == null) {
 throw new InvalidParameterException("service must not be null");
 }
 this.service = service;
}

// Set the other service to be used by this client
public void setOtherService(Service otherService) {
 if (otherService == null) {
 throw new InvalidParameterException("otherService must not be null");
 }
 this.otherService = otherService;
}

```
 نظرًا لأن هذه الحقن يحدث بشكل مستقل، فلا توجد طريقة لمعرفة متى ينتهي الحاقن من توصيل العميل. يمكن ترك التبعية فارغة ببساطة عن طريق الفشل في استدعاء أداة ضبطها. هذا يفرض التحقق من اكتمال الحقن من وقت تجميع العميل حتى وقت استخدامه. 

```
// Set the service to be used by this client
public void setService(Service service) {
 this.service = service;
}

// Set the other service to be used by this client
public void setOtherService(Service otherService) {
 this.otherService = otherService;
}

// Check the service references of this client
private void validateState() {
 if (service == null) {
 throw new IllegalStateException("service must not be null");
 }
 if (otherService == null) {
 throw new IllegalStateException("otherService must not be null");
 }
}

// Method that uses the service references
public void doSomething() {
 validateState();
 service.doYourThing();
 otherService.doYourThing();
}

```

#### مقارنة حقن الواجهة

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

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

لكي يكون لحقن الواجهة قيمة، التبعية يجب أن تقوم بشيء، بالإضافة إلى إرجاع مرجع لنفسها.. يمكن أن يكون هذا بمثابة مصنع أو مجمع فرعي لحل تبعيات أخرى، وبالتالي تجريد بعض التفاصيل من المجمع الرئيسي.. يمكن أن يكون عدًا مرجعيًا حتى تعرف التبعية عدد العملاء الذين يستخدمونه. إذا احتفظت التبعية بمجموعة من العملاء، فيمكنها لاحقًا حقنهم جميعًا بمثيل مختلف عن نفسها

```
// Service setter interface.
public interface ServiceSetter {
 public void setService(Service service);
}

// Client class
public class Client implements ServiceSetter {
 // Internal reference to the service used by this client.
 private Service service;

 // Set the service that this client is to use.
 @Override
 public void setService(Service service) {
 this.service = service;
 }
}

// Injector class
public class ServiceInjector {
 Set<ServiceSetter> clients;
 public void inject(ServiceSetter client) {
 clients.add(client);
 client.setService(new ServiceFoo());
 }
 public void switchToBar() {
 for (Client client : clients) {
 client.setService(new ServiceBar());
 }
 }
}

// Service classes
public class ServiceFoo implements Service {}
public class ServiceBar implements Service {}

```

### تجميع الأمثلة

يعد التجميع يدويًا داخل الطريقة (الدالة) (بالإنجليزية: main)‏ الرئيسية إحدى طرق تنفيذ حقن التبعية .

```
public class Injector {
 public static void main(String[] args) {
 // Build the dependencies first
 Service service = new ExampleService();

 // Inject the service, constructor style
 Client client = new Client(service);

 // Use the objects
 System.out.println(client.greet());
 }
}

```

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

قد لا يكون هذا البناء اليدوي في الطريقة الرئيسية مباشرأ وقد يتضمن استدعاء بناة أو مصانع أو أنماط بناء أخرى أيضًا. يمكن أن يكون هذا متقدمًا ومجرّدًا إلى حد ما. يتم تجاوز الخط من حقن التبعية اليدوي إلى حقن تبعية الإطار بمجرد أن كود البناء لم يعد مخصصًا للتطبيق بل أصبح عالميًا).

يمكن لإطارات مثل سبرينغ إنشاء هذه الكائنات نفسها وتوصيلها معًا قبل إرجاع مرجع إلى العميل. يمكن نقل جميع الإشارة إلى ExampleService الملموسة من الكود إلى بيانات التكوين.

```
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Injector {
 public static void main(String[] args) {
 // -- Assembling objects -- //
 BeanFactory beanfactory = new ClassPathXmlApplicationContext("Beans.xml");
 Client client = (Client) beanfactory.getBean("client");

 // -- Using objects -- //
 System.out.println(client.greet());
 }
}

```

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

```
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

 <bean id="service" class="ExampleService">
 </bean>

 <bean id="client" class="Client">
 <constructor-arg value="service" /> 
 </bean>
</beans>

```

في المثال أعلاه، لم يكن يتعين على العميل والخدمة الخضوع لأية تغييرات يوزودها إطار سبرينغ. يسمح لهم بالبقاء كبوجو(بالإنجليزية: POJOs )‏ بسيطة. يوضح هذا كيف يمكن لspring أن يربط الخدمات والعملاء الذين يجهلون تمامًا وجودها. لا يمكن قول ذلك إذا تمت إضافة التعليقات التوضيحية الخاصة بSpring إلى الأصناف. من خلال منع التعليقات التوضيحية الاستدعاءات الخاصة بسبرينغ من الانتشار بين العديد من الأصناف، يظل النظام معتمدًا بشكل فضفاض فقط على سبرينغ.
 قد يكون هذا مهمًا إذا كان النظام ينوي البقاء على قيد الحياة في سبرينغ. اختيار الحفاظ على POJOs صافية لا يأتي بدون تكلفة. بدلاً من بذل الجهد لتطوير ملفات التكوين المعقدة وصيانتها، من الممكن ببساطة استخدام التعليقات التوضيحية لوضع علامة على الأصناف) وترك سبرينغ يقوم بتتمة العمل. يمكن أن يكون حل التبعيات بسيطًا إذا اتبعت المصطلح عليه عادةً مثل المطابقة حسب النوع أو بالاسم. هذا هو اختيار الاصطلاح على التكوين
. ويمكن القول أيضًا أنه عند إعادة البناءإلى إطارآخر، فإن إزالة التعليقات التوضيحية المحددة للإطار ستكون جزءًا بسيطًا من المهمة

 ويتم الآن توحيد العديد من التعليقات التوضيحية بالحقن. 

```
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Injector {
 public static void main(String[] args) {
 // Assemble the objects
 BeanFactory beanfactory = new AnnotationConfigApplicationContext(MyConfiguration.class);
 Client client = beanfactory.getBean(Client.class);

 // Use the objects
 System.out.println(client.greet());
 }
}

```

```
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan
public class MyConfiguration {
 @Bean
 public Client client(ExampleService service) {
 return new Client(service);
 }
}

```

```
@Component
public class ExampleService {
 public String getName() {
 return "
 }
}

```

### مقارنة التجميع

لا تختلف تنفيذات الحاقن المختلفة (المصانع، مواقع الخدمة، وحاويات حقن التبعية فيما يتعلق بحقن التبعية. ما يحدث فرقاً هو المكان الذي يسمح لهم باستخدامه. قم بنقل الاستدعاءات إلى المصنع أو محدد الخدمة خارج العميل وإلى الرئيسية (بالإنجليزية: main)‏ والمفاجئ الرئيسي يجعل حاوية حقن التبعية جيدة إلى حد ما. من خلال نقل كل المعرفة عن الحاقن إلى الخارج، يتم ترك عميل نظيف، خالٍ من المعرفة بالعالم الخارجي. ومع ذلك، يمكن اعتبار أي كائن يستخدم كائنات أخرى عميلاً. الكائن الذي يحتوي على main ليس استثناء. هذا الكائن الرئيسي لا يستخدم حقن التبعية. في الواقع استخدام نمط محدد مواقع الخدمة. لا يمكن تجنب ذلك لأنه يجب أن يتم اختيار تنفذيات الخدمة في مكان ما.

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

### نمط حقن التبعية

كانت الأمثلة حتى الآن أمثلة بسيطة للغاية حول إنشاء سلسلة (سلسلة نصية). ومع ذلك، يمكن أنه يكون نمط حقن التبعية أكثر فائدة عند إنشاء رسم بياني للكائن حيث تتواصل الكائنات عبر الرسائل.

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

. 

```
public static void main(String[] args) throws IOException {

 // Construction code.
 Greeter greeter = new Greeter(System.out); // This may be many lines that connect many objects

 // Behavior code.
 greeter.greet(); // This is one call to one method on one object in the object graph
}

class Greeter {
 public void greet() {
 this.out.println("Hello world!");
 }
 public Greeter(PrintStream out) {
 this.out = out;
 }
 private PrintStream out;
}

```

### مثال أنغولار جي إس

في إطار عمل أنغولار، هناك ثلاث طرق فقط يمكن للمكون (الكائن أو الوظيفة) الوصول مباشرةً إلى تبعياته:

1. يمكن للمكون إنشاء التبعية، عادةً باستخدام عامل `new`.
2. يمكن للمكون أن يبحث عن التبعية بالإشارة إلى متغير عام.
3. يمكن أن ينتقل المكون إلى التبعية إليه عند الحاجة..

أول خيارين لإنشاء التبعيات أو البحث عنها ليسا الأمثل لأنهما يكودا التبعية بشكل ثابت للمكون.

. وهذا يجعل من الصعب، إن لم يكن من المستحيل، تعديل التبعيات. هذا يمثل مشكلة خاصة في الاختبارات، حيث من المستحسن في الغالب توفير تبعيات وهمية لعزل الاختبار.

الخيار الثالث هو الأكثر قابلية للتطبيق، لأنه يزيل مسؤولية تحديد موقع التبعية من المكون. يتم تسليم التبعية ببساطة إلى المكون.

```
function SomeClass(greeter) {
 this.greeter = greeter;
}

SomeClass.prototype.doSomething = function(name) {
 this.greeter.greet(name);
}

```

في المثال أعلاه، لا تهتم `SomeClass` بإنشاء أو تحديد مكان تبعية المحيي، بل يتم ببساطة تسليم المحيي عند إنشاء مثيل لها. هذا أمر مرغوب فيه، ولكنه يضع مسؤولية الحصول على التبعية على الكود الذي يبني بعض الأصناف `SomeClass`.

لإدارة مسؤولية إنشاء التبعية، يحتوي كل تطبيق أنغولار جي إس، على حاقن. الحاقن هو محدد مواقع الخدمة المسؤول عن البناء والبحث عن التبعيات.

فيما يلي مثال على استخدام خدمة الحاقن:

```
// Provide the wiring information in a module
var myModule = angular.module('myModule', []);

// Teach the injector how to build a greeter service.
// greeter is dependent on the $window service.
// The greeter service is an object that
// contains a greet method.
myModule.factory('greeter', function($window) {
 return {
 greet: function(text) {
 $window.alert(text);
 }
 };
});

```

قم بإنشاء حاقن جديد يمكنه توفير المكونات المعرفة في نموذج `myModule` وطلب خدمة المحيي من الحاقن. (يتم ذلك تلقائيًا تلقائيًا عن طريق أنغولار جي اس بووتستراب (بالإنجليزية: AngularJS bootstrap)‏.

```
var injector = angular.injector(['myModule', 'ng']);
var greeter = injector.get('greeter');

```
 إن طلب التبعيات يحل مشكلة التكويد الصلب، ولكنه يعني أيضًا أنه يجب تمرير الحاقن في كل التطبيق. تمرير الحاقن يخالف قانون ديميتر. لعلاج هذا، نستخدم تدوينًا توضيحيًا في قوالب HTML الخاصة بنا، لتسليم مسؤولية إنشاء المكونات إلى الحاقن، كما في هذا المثال:

```
<div ng-controller="MyController">
 <button ng-click="sayHello()">Hello</button>
</div>

```

```
function MyController($scope, greeter) {
 $scope.sayHello = function() {
 greeter.greet('Hello World');
 };
}

```

عندما يقوم أنغلار جي إس، بتجميع HTML، فإنه يعالج توجيه `ng-controller`، والذي بدوره يطلب من الحاقن إنشاء مثيل من وحدة التحكم وتبعياتها

.

```
injector.instantiate(MyController);

```

تمثيل صنف، فيمكنه تلبية جميع تبعيات `MyController` دون أن تعرف وحدة التحكم عن الحاقن. يعلن كود التطبيق ببساطة التبعيات التي يحتاجها، دون الحاجة إلى التعامل مع الحاقن. هذا الإعداد لا يخالف قانون ديميتر.

### سي شارب

مثال على حقن المنشئ، حقن المعيّن وحقن الواجهة على (#C)

```
using System;

namespace DependencyInjection
{
 // An interface for the library
 interface IGamepadFunctionality
 {
 String GetGamepadName();
 void SetVibrationPower(float InPower);
 }

 // Concrete implementation of the xbox controller functionality
 class XBoxGamepad : IGamepadFunctionality
 {
 readonly String GamepadName = "XBox Controller";
 float VibrationPower = 1.0f;
 public String GetGamepadName() => GamepadName;
 public void SetVibrationPower(float InPower) => VibrationPower = Math.Clamp(InPower, 0.0f, 1.0f);

 }

 // Concrete implementation of the playstation controller functionality
 class PlaystationJoystick : IGamepadFunctionality
 {
 readonly String ControllerName = "Playsation joystick";
 float VibratingPower = 100.0f;
 public String GetGamepadName() => ControllerName;
 public void SetVibrationPower(float InPower) => VibratingPower = Math.Clamp(InPower \* 100.0f, 0.0f, 100.0f);
 }

 // Concrete implementation of the steam controller functionality
 class SteamController : IGamepadFunctionality
 {
 readonly String JoystickName = "Steam controller";
 double Vibrating = 1.0;
 public String GetGamepadName() => JoystickName;
 public void SetVibrationPower(float InPower) => Vibrating = Convert.ToDouble(Math.Clamp(InPower, 0.0f, 1.0f));
 }

 // An interface for gamepad functionality injections
 interface IGamepadFunctionalityInjector
 {
 void InjectFunctionality(IGamepadFunctionality InGamepadFunctionality);
 }

 class CGamepad : IGamepadFunctionalityInjector
 {
 IGamepadFunctionality \_GamepadFunctionality;

 public CGamepad()
 {

 }
 // Constructor injection
 public CGamepad(IGamepadFunctionality InGamepadFunctionality) => \_GamepadFunctionality = InGamepadFunctionality;

 // Setter injection
 public void SetGamepadFunctionality(IGamepadFunctionality InGamepadFunctionality) => \_GamepadFunctionality = InGamepadFunctionality;

 // Interface injection
 public void InjectFunctionality(IGamepadFunctionality InGamepadFunctionality) => \_GamepadFunctionality = InGamepadFunctionality;

 public void Showcase()
 {
 String Message = String.Format("We're using the {0} right now, do you want to change the vibrating power?\r\n", \_GamepadFunctionality.GetGamepadName());
 Console.WriteLine(Message);
 }
 }

 enum EPlatforms: byte
 {
 Xbox,
 Playstation,
 Steam
 }

 class CGameEngine
 {
 EPlatforms \_Platform;
 CGamepad \_Gamepad;
 public void SetPlatform(EPlatforms InPlatform)
 {
 \_Platform = InPlatform;
 switch(\_Platform)
 {
 case EPlatforms.Xbox:

 // injects dependency on XBoxGamepad class through Constructor Injection
 \_Gamepad = new CGamepad(new XBoxGamepad());
 break;
 case EPlatforms.Playstation:
 \_Gamepad = new CGamepad();

 // injects dependency on PlaystationJoystick class through Setter Injection
 \_Gamepad.SetGamepadFunctionality(new PlaystationJoystick());
 break;
 case EPlatforms.Steam:
 \_Gamepad = new CGamepad();

 // injects dependency on SteamController class through Interface Injection
 \_Gamepad.InjectFunctionality(new SteamController());
 break;
 }

 \_Gamepad.Showcase();
 }
 }
 class Program
 {
 static void Main(string[] args)
 {
 Console.WriteLine("Hello World!");
 
 CGameEngine Engine = new CGameEngine();

 Engine.SetPlatform(EPlatforms.Steam);

 Engine.SetPlatform(EPlatforms.Xbox);

 Engine.SetPlatform(EPlatforms.Playstation);
 }
 }
}

```

ملحق: مسرد المصطلحات الإنجليزية
-------------------------------


|  |
| --- |
| مَسرد المفردات وفق أقسام المقالة |
| المقدمة |
| هندسة البرمجيات | software engineering |
| يتلقى فيها كائن كائنات أخرى | Object receives other objects |
| التبعيات | dependencies |
| في العلاقة النموذجية "باستخدام" | In the typical "using" relationship |
| عميل | (بالإنجليزية: client)‏ |
| المحقون | injected |
| خدمة | service |
| يمكن أن يكون الكود الذي ينقل الخدمة إلى العميل أنواعًا كثيرة ويسمى الحاقن | can be many kinds of things and is called the injector |
| الحاقن | injector |
| تمرير التبعية | passing of a dependency |
| الكائن (العميل) | client object |
| حالة العميل | client's state |
| بناء | build |
| العثور عليها | find the service |
| شرطاً أساسياً للنمط | fundamental requirement of the pattern |
| النية | intent |
| حقن التبعية | dependency injection |
| فصل الاهتمامات | [[:en:Separation of concerns|separation of concerns]] |
| زيادة إمكانية القراءة | increase readability |
| إعادة استخدام الكود | code reuse |
| شكل من أشكال التقنية الأوسع لعكس التحكم | broader technique of inversion of control |
| استدعاء بعض الخدمات | call some services |
| معرفة كيفية إنشاء هذه الخدمات | to know how to construct those service |
| يفوض | delegates |
| للكود الخارجي (الحاقن) | external code (the injector) |
| لا يُسمح للعميل باستدعاء كود الحاقن | The client is not allowed to call the injector code |
| الحاقن هو الذي يبني الخدمات | it is the injector that constructs the services |
| تمرير | passes |
| قد يتم بناؤها بواسطة الحاقن | be constructed by the injector |
| كيفية إنشاء الخدمات | how to construct the services |
| حتى الخدمات الفعلية التي يستخدمها | even which actual services it is using |
| معرفة الواجهات الجوهرية للخدمات | intrinsic interfaces of the services |
| يفصل مسؤولية "الاستخدام" | "responsibility of "use |
| مسؤولية "البناء" | "responsibility of "construction |
| نوايا |
| التطبيق | application |
| الصنف | class |
| مستقل عن كيفية إنشاء كائناته | be independent of how its objects are created |
| طريقة إنشاء الكائنات | way objects are created |
| 
```
في ملفات تكوين منفصلة
```
 | reated be specified in separate configuration files |
| تكوينات | configurations |
| دعم | support |
| إنشاء كائنات مباشرة داخل الصنف | Creating objects directly within the class |
| التمثيل | instantiation |
| يوقف الصنف عن إمكانية إعادة استخدامه | It stops the class from being reusable |
| ويجعل من الصعب اختبار الصنف | (بالإنجليزية: it makes the class hard to test class)‏ |
| لا يمكن استبدال الكائنات الحقيقية بكائنات وهمية | because real objects can not be replaced with mock objects |
| تفويض | delegate |
| مثيل | instantiation |
| لكائن مصنع | to a factory object |
| نمط تصميم | Abstract Factory |
| نظرة عامة |
| إنشاء تبعيات العميل | creation of a client's dependencies |
| سلوك العميل | client's behavior |
| لتصاميم البرنامج أن تكون مقترنة بشكل متساهل | program designs to be loosely coupled |
| متابعة انعكاس التبعية | to follow the dependency inversion |
| مبادئ المسؤولية واحدة | single responsibility principles |
| يتناقض بشكل مباشر مع نمط محدد مواقع الخدمة | It directly contrasts with the service locator pattern |
| للعملاء | clients |
| بمعرفة النظام الذي يستخدمونه للعثور على التبعيات | to know about the system they use to find dependencies |
| الحقن | injection |
| الوحدة الأساسية لحقن التبعية | the basic unit of dependency injection |
| تمرير المعلمة | "parameter passing" |
| يحمل | carries |
| ضمناً إضافياً | the added implication |
| يتم القيام به لعزل العميل عن التفاصيل | to isolate the client from details |
| يخالف قانون ديميتر | Law of Demeter. |

انظر أيضًا
----------

* مصنع (برمجة كائنية التوجه)
* عكس التحكم
* برنامج مساعد (حوسبة)
* نموذج الإستراتيجية
* أنجولار جي إس
* نمط محدد موقع الخدمة
* وسيط (برمجة حاسوب)

المراجع
-------

1. ↑  Component Relationship - an overview | ScienceDirect Topics نسخة محفوظة 2020-05-23 على موقع واي باك مشين.
2. ↑  I.T.، Titanium. "James Shore: Dependency Injection Demystified". *www.jamesshore.com*. مؤرشف من الأصل في 2020-03-09. اطلع عليه بتاريخ 2015-07-18.
3. ↑  "HollywoodPrinciple". *c2.com*. مؤرشف من الأصل في 2016-10-07. اطلع عليه بتاريخ 2015-07-19.
4. ↑  "The Dependency Injection design pattern - Problem, Solution, and Applicability". *w3sDesign.com*. مؤرشف من الأصل في 2020-05-23. اطلع عليه بتاريخ 2017-08-12.
5. ↑  
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). *Design Patterns: Elements of Reusable Object-Oriented Software*. Addison Wesley. ص. 87ff. ISBN:0-201-63361-2. مؤرشف من الأصل في 2020-05-23.`{{استشهاد بكتاب}}`: صيانة CS1: أسماء متعددة: قائمة المؤلفين (link)
6. ↑  Seemann، Mark. "Dependency Injection is Loose Coupling". *blog.ploeh.dk*. مؤرشف من الأصل في 2020-02-19. اطلع عليه بتاريخ 2015-07-28.
7. ↑  Niko Schwarz, Mircea Lungu, Oscar Nierstrasz, "Seuss: Decoupling responsibilities from static methods for fine-grained configurability", Journal of Object Technology, Volume 11, no. 1 (April 2012), pp. 3:1-23
8. ↑  "Passing Information to a Method or a Constructor (The Java™ Tutorials > Learning the Java Language > Classes and Objects)". *docs.oracle.com*. مؤرشف من الأصل في 2020-05-16. اطلع عليه بتاريخ 2015-07-18.
9. ↑  "A curry of Dependency Inversion Principle (DIP), Inversion of Control (IoC), Dependency Injection (DI) and IoC Container - CodeProject". *www.codeproject.com*. مؤرشف من الأصل في 2020-02-19. اطلع عليه بتاريخ 2015-08-08.
10. ↑  "How to force "program to an interface" without using a java Interface in java 1.6". *programmers.stackexchange.com*. مؤرشف من الأصل في 2016-08-11. اطلع عليه بتاريخ 2015-07-19.
11. ↑  "To "new" or not to "new"…". مؤرشف من الأصل في 2020-05-13. اطلع عليه بتاريخ 2015-07-18.
12. ↑  "How to write testable code". *www.loosecouplings.com*. مؤرشف من الأصل في 2020-02-19. اطلع عليه بتاريخ 2015-07-18.
13. ↑  "Writing Clean, Testable Code". *www.ethanresnick.com*. مؤرشف من الأصل في 2020-02-19. اطلع عليه بتاريخ 2015-07-18.
14. ↑  Sironi، Giorgio. "When to inject: the distinction between newables and injectables - Invisible to the eye". *www.giorgiosironi.com*. مؤرشف من الأصل في 2020-02-19. اطلع عليه بتاريخ 2015-07-18.
15. ↑  "Inversion of Control vs Dependency Injection". *stackoverflow.com*. مؤرشف من الأصل في 2020-04-23. اطلع عليه بتاريخ 2015-08-05.
16. ↑  "What is the difference between Strategy pattern and Dependency Injection?". *stackoverflow.com*. مؤرشف من الأصل في 2017-01-04. اطلع عليه بتاريخ 2015-07-18.
17. 1 2  
"Dependency Injection != using a DI container". *www.loosecouplings.com*. مؤرشف من الأصل في 2020-02-24. اطلع عليه بتاريخ 2015-07-18.
18. ↑  "Black Sheep » DIY-DI » Print". *blacksheep.parry.org*. مؤرشف من الأصل في 2015-06-27. اطلع عليه بتاريخ 2015-07-18.
19. ↑  3.1. Dependency injection — Python 3: From None to Machine Learning نسخة محفوظة 2020-05-23 على موقع واي باك مشين.
20. ↑   نسخة محفوظة 2019-11-16 على موقع واي باك مشين.
21. ↑   نسخة محفوظة 2019-03-20 على موقع واي باك مشين.
22. ↑  "The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 330". *jcp.org*. مؤرشف من الأصل في 2020-05-15. اطلع عليه بتاريخ 2015-07-18.
23. 1 2 3   نسخة محفوظة 2019-12-31 على موقع واي باك مشين.
24. ↑  "the urban canuk, eh: On Dependency Injection and Violating Encapsulation Concerns". *www.bryancook.net*. مؤرشف من الأصل في 2019-11-06. اطلع عليه بتاريخ 2015-07-18.
25. ↑  "The Dependency Injection Design Pattern". *msdn.microsoft.com*. مؤرشف من الأصل في 2015-07-02. اطلع عليه بتاريخ 2015-07-18.
26. ↑   نسخة محفوظة 2020-01-16 على موقع واي باك مشين.
27. ↑   نسخة محفوظة 2017-03-05 على موقع واي باك مشين.
28. ↑  "What are the downsides to using Dependency Injection?". *stackoverflow.com*. مؤرشف من الأصل في 2020-04-25. اطلع عليه بتاريخ 2015-07-18.
29. 1 2  "Dependency Injection Inversion - Clean Coder". *sites.google.com*. مؤرشف من الأصل في 2016-12-03. اطلع عليه بتاريخ 2015-07-18.
30. ↑  "Decoupling Your Application From Your Dependency Injection Framework". *InfoQ*. مؤرشف من الأصل في 2017-10-06. اطلع عليه بتاريخ 2015-07-18.
31. 1 2  "The Dependency Injection design pattern - Structure and Collaboration". *w3sDesign.com*. مؤرشف من الأصل في 2020-05-23. اطلع عليه بتاريخ 2017-08-12.
32. ↑  Martin Fowler (23 يناير 2004). "Inversion of Control Containers and the Dependency Injection pattern - Forms of Dependency Injection". Martinfowler.com. مؤرشف من الأصل في 2020-05-21. اطلع عليه بتاريخ 2014-03-22.
33. ↑  "Yan - Dependency Injection Types". Yan.codehaus.org. مؤرشف من الأصل في 2013-08-18. اطلع عليه بتاريخ 2013-12-11.
34. ↑  "AccessibleObject (Java Platform SE 7)". *docs.oracle.com*. مؤرشف من الأصل في 2019-01-18. اطلع عليه بتاريخ 2015-07-18.
35. ↑  Riehle، Dirk (2000)، *Framework Design: A Role Modeling Approach* (PDF)، Swiss Federal Institute of Technology، مؤرشف من الأصل (PDF) في 2019-01-09
36. ↑  
"Spring Tips: A POJO with annotations is not Plain". مؤرشف من الأصل في 2015-07-15. اطلع عليه بتاريخ 2015-07-18.
37. ↑  "Annotations in POJO – a boon or a curse? | Techtracer". 7 أبريل 2007. مؤرشف من الأصل في 2019-04-26. اطلع عليه بتاريخ 2015-07-18.
38. ↑  
*Pro Spring Dynamic Modules for OSGi Service Platforms*. APress. 17 فبراير 2009. ISBN:9781430216124. مؤرشف من الأصل في 2020-05-23. اطلع عليه بتاريخ 2015-07-06.
39. ↑  "Captain Debug's Blog: Is 'Convention Over Configuration' Going Too Far?". *www.captaindebug.com*. مؤرشف من الأصل في 2019-08-20. اطلع عليه بتاريخ 2015-07-18.
40. ↑  Decker، Colin. "What's the issue with @Inject? | Colin's Devlog". *blog.cgdecker.com*. مؤرشف من الأصل في 2019-03-05. اطلع عليه بتاريخ 2015-07-18.
41. ↑  Morling، Gunnar (18 نوفمبر 2012). "Dagger - A new Java dependency injection framework". *Dagger - A new Java dependency injection framework - Musings of a Programming Addict*. مؤرشف من الأصل في 2019-11-05. اطلع عليه بتاريخ 2015-07-18.
42. ↑  "The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 330". *www.jcp.org*. مؤرشف من الأصل في 2020-05-15. اطلع عليه بتاريخ 2015-07-18.

روابط خارجية
------------

* جذر التكوين بواسطة مارك Seemann
* دليل المبتدئين لحقن التبعية
* حقن التبعية والأشياء القابلة للاختبار: تصميم كائنات متقاربة وقابلة للاختبار - جيريمي ويسكوتن ؛ مجلة دكتور دوب، مايو 2006.
* أنماط التصميم: حقن التبعية - مجلة MSDN، سبتمبر 2005
* مقالة مارتن فاولر الأصلية التي أدخلت مصطلح حقن التبعية
* P من EAA: البرنامج المساعد
* التراث الهندسي الغني وراء حقن التبعية - أندرو ماكفي - تاريخ مصنف classلحقن التبعية.
* ما هو حقن التبعية؟ - تفسير بديل - جاكوب جينكوف
* كتابة كود أكثر قابلية للاختبار مع حقن التبعية - Developer.com، أكتوبر 2006
* نظرة عامة على إطار التوسعة المدارة - MSDN
* الوصف القديم لآلية التبعية بواسطة Hunt 1998
* إعادة بناء طريقك إلى حاوية حقن التبعية
* فهم DI في PHP
* لا تحتاج إلى حاوية حقن التبعية

|  |
| --- |
| **حقن التبعية** في المشاريع الشقيقة: |
|  | 
* صور وملفات صوتية من كومنز.
 |

* أيقونة بوابةبوابة برمجة الحاسوب
* أيقونة بوابةبوابة علم الحاسوب

| * ع
* ن
* ت
 أنماط تصميم البرمجيات (برمجة) |
| --- |
| إنشائي (Creational) | 
* Abstract factory
* نمط تصميم الباني
* حقن التبعية
* نمط طريقة المصنع
* Lazy initialization
* Multiton
* Object pool
* Prototype
* اكتساب الموارد تهيئة
* النمط المفرد

 |
| هيكلي (Structural) | 
* نمط المحول
* نموذج التصميم جسر
* نموذج التصميم المجمع
* نموذج التصميم ديكور
* Delegation
* نمط واجهة المبنى
* نموذج التصميم وزن الذبابة
* Front controller
* Marker interface
* Module
* نمط الوكيل
* Twin

 |
| سلوكي (Behavioral) | 
* Blackboard
* Chain of responsibility
* Command
* Interpreter
* نمط المكرر
* Mediator
* Memento
* Null object
* المراقب (نموذج تصميم)
* Servant
* Specification
* State
* نموذج الإستراتيجية
* Template method
* Visitor

 |
| وظيفي (Functional) | 
* مونويد
* Functor
* Applicative
* Monad
* Comonad
* Free monad
* HOF
* Currying
* Function composition
* Closure
* المولد

 |
| متزامن (Concurrency) | 
* Active object
* Actor
* Balking
* حاجز (حوسبة)
* Binding properties
* Coroutine
* Compute kernel
* Double-checked locking
* Event-based asynchronous
* ليف
* Futex
* Futures and promises
* Guarded suspension
* Immutable object
* Join
* Lock
* صيغة التراسل
* Monitor
* Nuclear
* Proactor
* Reactor
* Read write lock
* Scheduler
* STM
* Thread pool
* Thread-local storage

 |
| معماري (Architectural) | 
* \* ADR
* نمط التسجيل النشط
* نمط الوسيط
* نموذج الخادم والعميل
* هندسة البرمجيات بالمكونات
* DAO
* كائن نقل البيانات
* تصميم موجه بالمجال
* ECB
* ECS
* EDA
* Front controller
* Identity map
* Interceptor
* Implicit invocation
* عكس التحكم
* Model 2
* MOM
* Microservices
* MVA
* نمط وعرض ومتحكم
* MVP
* MVVM
* Monolithic
* عمارة متعددة الطبقات
* Naked objects
* ORB
* ند لند
* Publish–subscribe
* PAC
* رست
* بنية خدمية
* نمط محدد موقع الخدمة
* SN
* SBA
* Specification

 |
| توزيع سحابي (Cloud Distributed) | 
* Ambassador
* Anti-Corruption Layer
* Bulkhead
* Cache-Aside
* Circuit Breaker
* CQRS
* Compensating Transaction
* Competing Consumers
* Compute Resource Consolidation
* Event Sourcing
* External Configuration Store
* Federated Identity
* Gatekeeper
* فهرس قاعدة بيانات
* Leader Election
* نموذج الهيكلة والتجميع
* Materialized View
* Pipes
* Filters
* Priority Queue
* Publisher-Subscriber
* Queue-Based Load Leveling
* Retry
* Scheduler Agent Supervisor
* Sharding
* Sidecar
* Strangler
* Throttling
* Valet Key

 |
| أخرى | 
* Business delegate
* Composite entity
* Intercepting filter
* Lazy loading
* Mangler
* غرض مقلد
* Type tunnel
* Method chaining

 |
| كتب | 
* *خطط التصميم*
* *Enterprise Integration Patterns*
* *Code Complete*
* *POSA*

 |
| أشخاص | 
* كريستوفر الكسندر
* إريك جاما
* رالف جونسن
* John Vlissides
* Grady Booch
* كينت بيك
* وورد كانينغهام
* مارتن فاولر
* روبرت سيسيل مارتن
* Jim Coplien
* دوغلاس س. شميت
* Linda Rising

 |
| مجتمعات (Communities) | 
* The Hillside Group
* The Portland Pattern Repository

 |