حقن التبعية في C#: دليل شامل مع أمثلة

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

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

ابدأ الدورة

Dependency Injection في C#: ما هو ولماذا هو مطلوب



Dependency Injection (DI) هو أحد أنماط التصميم الرئيسية التي تسمح بإنشاء تطبيقات C# ضعيفة الارتباط وسهلة الاختبار. بدلاً من أن يقوم الفصل (class) بإنشاء تبعياته بنفسه (مثل كائنات العمل مع قاعدة البيانات أو التسجيل)، يتم تمرير هذه التبعيات (حقنها) من الخارج. وهذا يحقق مبدأ Inversion of Control (IoC) - حيث يتم نقل التحكم إلى حاوية خارجية.



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



المبادئ الأساسية لـ Dependency Injection



يعتمد DI على ثلاث طرق أساسية لحقن التبعيات. دعنا نستعرض كل منها.



1. الحقن عبر المُنشئ (Constructor Injection)

الطريقة الأكثر شيوعًا والمفضلة. يتم تمرير التبعيات عبر معاملات المُنشئ للفصل.



public interface ILogger{    void Log(string message);}

public class ConsoleLogger : ILogger{ public void Log(string message) => Console.WriteLine(message);}

public class OrderService{ private readonly ILogger _logger;

// حقن التبعية عبر المُنشئ public OrderService(ILogger logger) { _logger = logger; }

public void ProcessOrder(int orderId) { _logger.Log($"معالجة الطلب {orderId}"); // منطق الأعمال }}


2. الحقن عبر الخاصية (Property Injection)

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



public class OrderService{    public ILogger Logger { get; set; }

public void ProcessOrder(int orderId) { if (Logger == null) throw new InvalidOperationException("Logger لم يتم تعيينه"); Logger.Log($"معالجة الطلب {orderId}"); }}


3. الحقن عبر الطريقة (Method Injection)

يتم تمرير التبعية كمعامل للطريقة. يُستخدم نادرًا، عادةً للتبعيات المؤقتة.



public class OrderService{    public void ProcessOrder(int orderId, ILogger logger)    {        logger.Log($"معالجة الطلب {orderId}");    }}


تسجيل التبعيات في حاوية .NET



في .NET الحديث (ASP.NET Core, Console, Worker Services) يتم استخدام حاوية DI المدمجة. يتم التسجيل في طريقة ConfigureServices أو عند إنشاء ServiceCollection.



هناك ثلاثة أعمار (lifetimes) للخدمات المسجلة:



  • Transient - يتم إنشاء مثيل جديد في كل مرة يتم طلبه. مناسب للخدمات الخفيفة وقصيرة العمر.
  • Scoped - مثيل واحد لكل طلب HTTP (أو نطاق). يُستخدم مع Entity Framework DbContext.
  • Singleton - مثيل واحد للتطبيق بأكمله. مناسب للتخزين المؤقت والإعدادات ومسجلات الأحداث.


// مثال لـ ASP.NET Corepublic class Startup{    public void ConfigureServices(IServiceCollection services)    {        // التسجيل بواجهة        services.AddTransient<ILogger, ConsoleLogger>();        services.AddScoped<IOrderRepository, OrderRepository>();        services.AddSingleton<IConfiguration, ConfigurationManager>();

// التسجيل بدون واجهة (فصل محدد) services.AddTransient<OrderService>(); }}

// الاستخدام في المتحكم (Controller)public class OrderController : ControllerBase{ private readonly OrderService _orderService;

public OrderController(OrderServi

المدونات

توصيات الكتب