आपका कोड सिर्फ कॉल आने पर ही क्यों जागता है?
\nकल्पना कीजिए कि आप एक बड़े हवाई अड्डे के डिस्पैचर हैं। विमान आ रहे हैं, यात्री जल्दी में हैं, ईंधन ट्रक चक्कर लगा रहे हैं। अगर आप खुद हर पायलट के पास जाकर पूछें, "क्या उतर गए? अब? अब?" — तो आप पागल हो जाएंगे। इसके बजाय, आप कहते हैं, "जब उतरो — कॉल करो।" और सिस्टम परफेक्ट काम करता है।
\nयही है C# में Event-Driven आर्किटेक्चर। बार-बार ऑब्जेक्ट्स से पूछने (pull) के बजाय, हम इवेंट्स (push) की सदस्यता लेते हैं। कोड रिएक्टिव, स्केलेबल और सबसे ज़रूरी, लाइव बन जाता है। इस लेख में, हम C# में ऐसे सिस्टम को शुरू से बनाना सीखेंगे, जिसमें भाषा के बिल्ट-इन मैकेनिज़्म और एडवांस्ड पैटर्न का उपयोग होगा।
\n\nEvent-Driven आर्किटेक्चर क्या है? बोरिंग थ्योरी नहीं
\nEvent-Driven (इवेंट-ड्रिवन) आर्किटेक्चर एक ऐसा दृष्टिकोण है जहां प्रोग्राम का प्रवाह इवेंट्स द्वारा निर्धारित होता है: क्लिक, कतारों से संदेश, डेटा में बदलाव या बाहरी सिग्नल। C# में, यह अवधारणा सीधे भाषा में डेलीगेट्स (delegates) और इवेंट्स (events) के माध्यम से बनाई गई है।
\nमुख्य सिद्धांत है लूज़ कपलिंग (loose coupling)। इवेंट भेजने वाला (प्रकाशक) प्राप्तकर्ताओं (सब्सक्राइबर्स) के बारे में कुछ नहीं जानता। वह बस चिल्लाता है: "कुछ ज़रूरी हुआ है!" — और इस पर कौन और कैसे प्रतिक्रिया करेगा, यह डायनामिक रूप से तय होता है।
\nयह रियल प्रोजेक्ट्स के लिए क्यों शानदार है?
\n- \n
- स्केलेबिलिटी: नया सब्सक्राइबर जोड़ना — उसे न्यूज़लेटर में सब्सक्राइब करने जैसा है। प्रकाशक का कोड नहीं बदलता। \n
- टेस्टेबिलिटी: आप सब्सक्राइबर्स को अलग-थलग करके टेस्ट कर सकते हैं, उन्हें फेक इवेंट्स देकर। \n
- रिएक्टिविटी: सिस्टम खुद बदलावों पर प्रतिक्रिया करता है, बिना खाली पूछताछ पर संसाधन बर्बाद किए। \n
बेसिक मैकेनिज़्म: C# में डेलीगेट्स और इवेंट्स
\nआर्किटेक्चर बनाने से पहले, आइए बुनियादी बातें समझें। C# में, इवेंट सिर्फ एक विशेष डेलीगेट है जिसमें event मॉडिफायर होता है। डेलीगेट एक प्रकार है जो एक मेथड (या कई मेथड्स) का रेफरेंस स्टोर करता है।
पहला Event-Driven कोड लिखें
\nकल्पना करें कि हम एक स्मार्ट होम सिस्टम बना रहे हैं। मोशन सेंसर सिग्नल भेजता है जब कोई अंदर आता है।
\n\npublic class MotionSensor\n{\n // 1. डेलीगेट घोषित करें (इवेंट का प्रकार)\n public delegate void MotionDetectedHandler(object sender, MotionEventArgs e);\n \n // 2. इवेंट घोषित करें\n public event MotionDetectedHandler OnMotionDetected;\n\n public void Detect(string location)\n {\n Console.WriteLine($"[सेंसर] {location} में हलचल!");\n \n // 3. इवेंट को कॉल करें (केवल अगर सब्सक्राइबर हों)\n OnMotionDetected?.Invoke(this, new MotionEventArgs(location));\n }\n}\n\npublic class MotionEventArgs : EventArgs\n{\n public string Location { get; }\n public DateTime Timestamp { get; } = DateTime.UtcNow;\n\n public MotionEventArgs(string location)\n {\n Location = location;\n }\n}\n\n// सब्सक्राइबर — लैंप\npublic class SmartLight\n{\n public void OnMotion(object sender, MotionEventArgs e)\n {\n if (e.Location == "लिविंग रूम")\n Console.WriteLine($"[लैंप] {e.Location} में लाइट चालू कर रहा हूँ!");\n else\n Console.WriteLine($"[लैंप] {e.Location} को इग्नोर कर रहा हूँ।");\n }\n}\n\n// उपयोग\nvar sensor = new MotionSensor();\nvar light = new SmartLight();\n\n// सेंसर के इवेंट पर लैंप को सब्सक्राइब करें\nsensor.OnMotionDetected += light.OnMotion;\n\nsensor.Detect("लिविंग रूम"); // लैंप काम करेगा\nsensor.Detect("किचन"); // "किचन को इग्नोर कर रहा हूँ।"\n\nज़रूरी: ?.Invoke का उपयोग इवेंट को कॉल करने का थ्रेड-सेफ तरीका है। null जांच के बिना, अगर कोई सब्सक्राइबर नहीं है तो आपको NullReferenceException मिल सकता है।
एडवांस्ड लेवल: EventBus और लूज़ कपलिंग
\nडायरेक्ट सब्सक्रिप्शन छोटे सिस्टम के लिए ठीक है, लेकिन