في هذه الصفحة
المقدمة
في تطبيقات .NET الكبيرة والمعقدة، بنحتاج في كثير من الأحيان أن الـ (objects) تعتمد على بعضها البعض، مما يعقد عملية الصيانة والاختبار.
على سبيل المثال، إذا كان لديك (Service) تعتمد على (Interfaces) متعددة أو قاعدة بيانات، فمن الأفضل أن يتم حقن هذه الاعتمادات (dependencies) بدلاً من إنشاء الـ Objects داخل الكود بشكل مباشر.
الفكرة هي فصل مسؤولية إنشاء الـ Objects عن باقي التطبيق، مما يسهل تحديث أو استبدال أي جزء من التطبيق.
الفكرة الأساسية للـ Dependency Injection
الـ Dependency Injection تعتبر طريقة لفصل الـ Objects وتوفيرها بشكل مركزي ، الـ DI Container يقوم بإدارة الـ Objects وتوفيرها عند الحاجة. بدلًا من إنشاء الـ Objects داخل الكود، نقوم "حقن" (inject) الـ Objects المطلوبة عبر الطرق المختلفة لـ DI.
وهنالك أكثر من نوع لتحقيق الـ Dependency Injection :
- Constructor Injection
- Property Injection
- Method Injection
الـ Constructor Injection
بنمرر الـ dependencies من خلال الـconstructor، وهي أكثر الطرق شيوعًا. دي الطريقة الأكثر استخدامًا لأنها تجعل من السهل تحديد جميع الـ dependencies عند إنشاء الـ Object.
مزاياها: تجعل الكود أكثر وضوحًا وسهولة في الفهم. كل شيء واضح في الـconstructor.
مثال بسيط عن الـ Constructor Injection
// تعريف Interface للوظيفة الأساسية
public interface IGreetingService {
string Greet(string name);
}
// تعريف الكلاس الذي ينفّذ الـ Interface
public class GreetingService : IGreetingService {
public string Greet(string name) => $"Hello, {name}!";
}
// إضافة الـdependency للـ DI Container في ASP.NET Core
public void ConfigureServices(IServiceCollection services) {
services.AddScoped<IGreetingService, GreetingService>(); //Scoped تعني أنها سيتم إنشاؤها في بداية الطلب وتنتهي في نهايته
}
// استخدام DI داخل Controller:
public class HomeController : Controller {
private readonly IGreetingService _greetingService;
// حقن الـdependency من خلال الـconstructor
public HomeController(IGreetingService greetingService) {
_greetingService = greetingService;
}
public IActionResult Index() {
var message = _greetingService.Greet("Alaa");
return View("Message", message);
}
}
في المثال الذي ذكرناه، قمنا بتمرير الـIGreetingService من خلال الـconstructor.
الـ Property Injection
بنمرر ال ـdependencies عن طريق الـ (Properties) بعد إنشاء الـ Object. هذه الطريقة أقل شيوعًا وقد تؤدي إلى مشاكل إذا تم استخدامها بشكل مفرط.
مثال: لو كنت تستخدم خصائص بدلًا من الـconstructor، يمكن أن يختلف الكود ليشمل تعيين الـ Object في الـproperties بدلاً من الـconstructor.
الـ Method Injection
يتم تمرير الـ dependencies كـ (parameters) لـ Functions معينة. تستخدم هذه الطريقة عندما تحتاج إلى توفير الـ dependency لعملية معينة فقط.
مثال: في حالة معينة، قد تحتاج فقط إلى إمداد الـ Function بـ Objects محددة دون إنشاء الـ Object على مستوى التطبيق بأكمله.