自定義的事件管理器
周銀輝
大多數框架下都提供了事件管理器的,但不使用框架時為了讓事件傳送者和事件接收者之間解耦,就可以如下寫個簡單的
public enum EventAdministratorEventTypes { ApplicationStartup, //在這裡新增你需要的事件 } public class EventAdministratorEventArgs : EventArgs { public object Arg { get; protected set; } public EventAdministratorEventArgs(object arg) { Arg = arg; } } public class EventAdministrator { private static EventAdministrator instance; public static EventAdministrator Instance { get { return instance ?? (instance = new EventAdministrator()); } } /// <summary> /// 用於儲存event和它對於的回撥函式列表的字典(event 和 callback是一對多的關係) /// </summary> private readonly Dictionary<EventAdministratorEventTypes, List<EventHandler<EventAdministratorEventArgs>>> eventAndCallbackBuffer = new Dictionary<EventAdministratorEventTypes, List<EventHandler<EventAdministratorEventArgs>>>(); private void AddCallbackForEvent(EventAdministratorEventTypes eventName, EventHandler<EventAdministratorEventArgs> callback) { if (!eventAndCallbackBuffer.ContainsKey(eventName)) { eventAndCallbackBuffer.Add(eventName, new List<EventHandler<EventAdministratorEventArgs>>()); } var callbackList = eventAndCallbackBuffer[eventName]; //新增時判定不存在為了防止多次註冊後引起多次呼叫回撥函式 if (!callbackList.Contains(callback)) { callbackList.Add(callback); } } /// <summary> /// 註冊為事件接受者 /// </summary> /// <param name="eventName">事件名稱</param> /// <param name="callback">事件發生時的回撥函式</param> public void Register(EventAdministratorEventTypes eventName, EventHandler<EventAdministratorEventArgs> callback) { AddCallbackForEvent(eventName, callback); } /// <summary> /// 觸發一個事件 /// </summary> /// <param name="sender">觸發者</param> /// <param name="eventName">事件名稱</param> /// <param name="args">觸發該事件時所帶的引數</param> public void Send(object sender, EventAdministratorEventTypes eventName, EventAdministratorEventArgs args) { if (!eventAndCallbackBuffer.ContainsKey(eventName)) { Logger.Warning("EventAdministrator:事件"+eventName+"被觸發,但沒有任何物件註冊該事件." + " 導致這個情況的原因可能有:程式碼中沒有呼叫相應的Register函式來註冊該事件; 或者 事件的Send函式發生在Register之前"); return; } var callbackList = eventAndCallbackBuffer[eventName]; foreach (var callback in callbackList) { callback.Invoke(sender, args); } } } }