आप शब्दकोश को इंजेक्ट करने के लिए Spring.NET जैसे कुछ प्रकार के आईओसी फ्रेमवर्क का भी उपयोग कर सकते हैं। इस तरह, यदि आपको कोई नया संदेश प्रकार मिलता है, तो आपको इस केंद्रीय केंद्र को फिर से कंपाइल करने की आवश्यकता नहीं है - बस एक कॉन्फ़िगरेशन फ़ाइल बदलें।
लंबे समय से प्रतीक्षा उदाहरण:
एक नया कंसोल अनुप्रयोग, उदाहरण नामित बनाएँ, और जोड़ने के इस:
using System;
using System.Collections.Generic;
using Spring.Context.Support;
namespace Example
{
internal class Program
{
private static void Main(string[] args)
{
MessageBroker broker = (MessageBroker) ContextRegistry.GetContext()["messageBroker"];
broker.Dispatch(null, new Type1EventArgs());
broker.Dispatch(null, new Type2EventArgs());
broker.Dispatch(null, new EventArgs());
}
}
public class MessageBroker
{
private Dictionary<Type, object> handlers;
public Dictionary<Type, object> Handlers
{
get { return handlers; }
set { handlers = value; }
}
public void Dispatch<T>(object sender, T e) where T : EventArgs
{
object entry;
if (Handlers.TryGetValue(e.GetType(), out entry))
{
MessageHandler<T> handler = entry as MessageHandler<T>;
if (handler != null)
{
handler.HandleMessage(sender, e);
}
else
{
//I'd log an error here
Console.WriteLine("The handler defined for event type '" + e.GetType().Name + "' doesn't implement the correct interface!");
}
}
else
{
//I'd log a warning here
Console.WriteLine("No handler defined for event type: " + e.GetType().Name);
}
}
}
public interface MessageHandler<T> where T : EventArgs
{
void HandleMessage(object sender, T message);
}
public class Type1MessageHandler : MessageHandler<Type1EventArgs>
{
public void HandleMessage(object sender, Type1EventArgs args)
{
Console.WriteLine("Type 1, " + args.ToString());
}
}
public class Type2MessageHandler : MessageHandler<Type2EventArgs>
{
public void HandleMessage(object sender, Type2EventArgs args)
{
Console.WriteLine("Type 2, " + args.ToString());
}
}
public class Type1EventArgs : EventArgs {}
public class Type2EventArgs : EventArgs {}
}
और एक app.config फ़ाइल:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object id="messageBroker" type="Example.MessageBroker, Example">
<property name="handlers">
<dictionary key-type="System.Type" value-type="object">
<entry key="Example.Type1EventArgs, Example" value-ref="type1Handler"/>
<entry key="Example.Type2EventArgs, Example" value-ref="type2Handler"/>
</dictionary>
</property>
</object>
<object id="type1Handler" type="Example.Type1MessageHandler, Example"/>
<object id="type2Handler" type="Example.Type2MessageHandler, Example"/>
</objects>
</spring>
</configuration>
आउटपुट:
Type 1, Example.Type1EventArgs
Type 2, Example.Type2EventArgs
No handler defined for event type: EventArgs
जैसा कि आप देख सकते हैं, MessageBroker
किसी भी हैंडलर के बारे में नहीं जानता है, और हैंडलर को MessageBroker
के बारे में पता नहीं है। ऐप में सभी मानचित्रण किया जाता है।कॉन्फ़िगरेशन फ़ाइल, ताकि यदि आपको कोई नया ईवेंट प्रकार संभालने की आवश्यकता है, तो आप इसे कॉन्फ़िगरेशन फ़ाइल में जोड़ सकते हैं। यह विशेष रूप से अच्छा है अगर अन्य टीम घटना प्रकारों और हैंडलर को परिभाषित कर रही हैं - वे सिर्फ अपनी सामग्री को एक डीएल में संकलित कर सकते हैं, आप इसे अपनी तैनाती में छोड़ दें और बस मैपिंग जोड़ें।
डिक्शनरी में MessageHandler<>
की बजाय टाइप ऑब्जेक्ट के मान हैं क्योंकि वास्तविक हैंडलर को MessageHandler<EventArgs>
पर नहीं डाला जा सकता है, इसलिए मुझे थोड़ा सा हैक करना पड़ा। मुझे लगता है कि समाधान अभी भी साफ है, और यह मैपिंग त्रुटियों को अच्छी तरह से संभालता है। ध्यान दें कि आपको इस प्रोजेक्ट में Spring.Core.dll को संदर्भित करने की भी आवश्यकता होगी। आप पुस्तकालय here, और प्रलेखन here पा सकते हैं। इसके लिए प्रासंगिक है। यह भी ध्यान रखें, इसके लिए Spring.NET का उपयोग करने की कोई आवश्यकता नहीं है - यहां महत्वपूर्ण विचार निर्भरता इंजेक्शन है। किसी भी तरह, ब्रोकर को एक्स के प्रकार के संदेश भेजने के लिए कुछ कहने की आवश्यकता होगी, और निर्भरता इंजेक्शन के लिए आईओसी कंटेनर का उपयोग करना ब्रोकर को एक्स के बारे में नहीं पता, और इसके विपरीत है।
कुछ अन्य अतः आईओसी और डि से संबंधित सवाल:
मुझे यहां प्रतिक्रियाएं पसंद हैं लेकिन शायद कुछ जगह जैसे RefactorMyCode.com इसके लिए एक बेहतर जगह हो सकती है। हर किसी के लिए उस साइट पर उनके जवाब में कोड पोस्ट करना थोड़ा आसान है। –
ठीक है, मैंने उदाहरण पोस्ट किया है, इसे उत्तर दें –