C# में Dependency Injection: यह क्या है और इसकी आवश्यकता क्यों है
Dependency Injection (DI) एक प्रमुख डिज़ाइन पैटर्न है जो C# में कमजोर रूप से जुड़े और आसानी से परीक्षण योग्य एप्लिकेशन बनाने में मदद करता है। क्लास द्वारा स्वयं अपनी निर्भरताएँ (जैसे डेटाबेस या लॉगिंग के लिए ऑब्जेक्ट) बनाने के बजाय, ये निर्भरताएँ बाहर से प्रदान (इंजेक्ट) की जाती हैं। यह Inversion of Control (IoC) सिद्धांत को लागू करता है — नियंत्रण एक बाहरी कंटेनर को स्थानांतरित कर दिया जाता है।
.NET इकोसिस्टम में, ASP.NET Core से शुरू करके DI एक डी-फैक्टो मानक बन गया है। अंतर्निहित निर्भरता कंटेनर (Microsoft.Extensions.DependencyInjection के माध्यम से) निर्भरताओं को पंजीकृत और हल करना आसान बनाता है। इस लेख में, हम C# में DI के सिद्धांत, व्यावहारिक उदाहरण और सर्वोत्तम प्रथाओं पर चर्चा करेंगे।
Dependency Injection के मूल सिद्धांत
DI निर्भरता इंजेक्शन के तीन बुनियादी तरीकों पर आधारित है। आइए उनमें से प्रत्येक पर नज़र डालें।
1. कंस्ट्रक्टर के माध्यम से इंजेक्शन
यह सबसे सामान्य और पसंदीदा तरीका है। निर्भरताएँ क्लास के कंस्ट्रक्टर पैरामीटर के रूप में पास की जाती हैं।
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. प्रॉपर्टी के माध्यम से इंजेक्शन
निर्भरता एक पब्लिक प्रॉपर्टी के माध्यम से सेट की जाती है। यह कम पसंदीदा है क्योंकि यह निर्भरता को वैकल्पिक बनाता है और रनटाइम पर त्रुटियाँ पैदा कर सकता है।
public class OrderService{ public ILogger Logger { get; set; }
public void ProcessOrder(int orderId) { if (Logger == null) throw new InvalidOperationException("Logger सेट नहीं है"); Logger.Log($"ऑर्डर {orderId} प्रोसेस किया जा रहा है"); }}3. मेथड के माध्यम से इंजेक्शन
निर्भरता को मेथड पैरामीटर के रूप में पास किया जाता है। इसका उपयोग शायद ही कभी किया जाता है, आमतौर पर अस्थायी निर्भरताओं के लिए।
public class OrderService{ public void ProcessOrder(int orderId, ILogger logger) { logger.Log($"ऑर्डर {orderId} प्रोसेस किया जा रहा है"); }}.NET कंटेनर में निर्भरताओं का पंजीकरण
आधुनिक .NET (ASP.NET Core, Console, Worker Services) में अंतर्निहित DI-कंटेनर का उपयोग किया जाता है। पंजीकरण ConfigureServices मेथड में या ServiceCollection बनाते समय होता है।
पंजीकृत सेवाओं के लिए तीन जीवनकाल (lifetime) होते हैं:
- Transient — अनुरोध करने पर हर बार एक नया इंस्टेंस बनाया जाता है। हल्की, अल्पकालिक सेवाओं के लिए उपयुक्त।
- Scoped — प्रति HTTP-अनुरोध (या scope) एक इंस्टेंस। Entity Framework DbContext के लिए उपयोग किया जाता है।
- Singleton — पूरे एप्लिकेशन के लिए एक इंस्टेंस। कैश, सेटिंग्स, लॉगर्स के लिए उपयुक्त।
// ASP.NET Core के लिए उदाहरणpublic class Startup{ public void ConfigureServices(IServiceCollection services) { // इंटरफ़ेस के साथ पंजीकरण services.AddTransient<ILogger, ConsoleLogger>(); services.AddScoped<IOrderRepository, OrderRepository>(); services.AddSingleton<IConfiguration, ConfigurationManager>();
// बिना इंटरफ़ेस के पंजीकरण (विशिष्ट क्लास) services.AddTransient<OrderService>(); }}
// कंट्रोलर में उपयोगpublic class OrderController : ControllerBase{ private readonly OrderService _orderService;
public OrderController(OrderServi
```