حاوية حقن التبعيات (Dependency Injection) لـ C# (.NET) — دليل شامل

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

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

ابدأ الدورة

حاوية حقن التبعيات (Dependency Injection) لـ C# (.NET): دليل شامل



حقن التبعيات (DI) هو أحد المبادئ الأساسية في التطوير الحديث باستخدام C# (.NET)، والذي يسمح بإنشاء تطبيقات ضعيفة الاقتران، قابلة للاختبار وسهلة الصيانة. في النظام البيئي لـ .NET، الأداة الرئيسية لتنفيذ حقن التبعيات هي الحاوية المدمجة من حزمة Microsoft.Extensions.DependencyInjection. في هذه المقالة، سنشرح بالتفصيل ما هي حاوية DI، وكيفية إعدادها، وما هي دورات الحياة الموجودة، وكيفية استخدامها بشكل صحيح في المشاريع الحقيقية.



ما هي حاوية حقن التبعيات (Dependency Injection)؟



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



المزايا الرئيسية لاستخدام حاوية DI:

  • تقليل اقتران الكود — تعتمد الفئات على التجريدات (الواجهات) بدلاً من التطبيقات الملموسة.
  • تبسيط الاختبار — سهولة استبدال التبعيات بكائنات وهمية (mock).
  • إدارة مركزية لدورة الحياة — تتحكم في وقت إنشاء الكائنات وتدميرها.
  • زيادة المرونة — يمكن تغيير التطبيقات دون تعديل كود المستهلكين.


تثبيت وإعداد حاوية DI



في مشاريع .NET الحديثة (ASP.NET Core، Console، Worker Services)، حاوية DI مدمجة بالفعل. لاستخدامها، يكفي إضافة الحزمة إلى المشروع:



dotnet add package Microsoft.Extensions.DependencyInjection


بعد ذلك، يتم إنشاء مثيل من IServiceCollection، حيث يتم تسجيل جميع التبعيات. لنلقِ نظرة على مثال بسيط لتسجيل الخدمات:



using Microsoft.Extensions.DependencyInjection;

// تعريف الواجهة وتطبيقهاpublic interface IMessageService{ void Send(string message);}

public class EmailService : IMessageService{ public void Send(string message) { Console.WriteLine($"Email sent: {message}"); }}

// إعداد الحاويةvar services = new ServiceCollection();services.AddTransient<IMessageService, EmailService>();

// بناء مزود الخدماتvar serviceProvider = services.BuildServiceProvider();

// الحصول على مثيل الخدمةvar messageService = serviceProvider.GetService<IMessageService>();messageService.Send("Hello from DI!");


دورات حياة التبعيات



تدعم حاوية DI ثلاثة أوضاع رئيسية لإدارة عمر الكائنات:



  • Transient (AddTransient) — كل طلب ينشئ مثيلًا جديدًا. مناسب للخدمات خفيفة الوزن بدون حالة.
  • Scoped (AddScoped) — مثيل واحد لكل نطاق (مثل طلب HTTP في ASP.NET Core). مثالي للخدمات ذات الحالة ضمن عملية واحدة.
  • Singleton (AddSingleton) — مثيل واحد للتطبيق بأكمله. يُستخدم للتخزين المؤقت، السجلات، الإعدادات.


مثال على التسجيل بدورات حياة مختلفة:



services.AddTransient<ITransientService, TransientService>();services.AddScoped<IScopedService, ScopedService>();services.AddSingleton<ISingletonService, SingletonService>();


هام: إذا كانت الخدمة تعتمد على خدمة أخرى بدورة حياة أقصر، فقد يؤدي ذلك إلى أخطاء (مثل Singleton يستخدم Scoped). تُسمى هذه الحالات "التبعيات المحتجزة" (captive dependencies) ويجب تجنبها.



حقن التبعيات عبر المُنشئ



الطريقة الأكثر شيوعًا للحقن هي عبر المُنشئ. تقوم الحاوية تلقائيًا بحل جميع التبعيات

توصيات