自定義的事件管理器

周銀輝發表於2014-06-20

            自定義的事件管理器

              周銀輝

 

大多數框架下都提供了事件管理器的,但不使用框架時為了讓事件傳送者和事件接收者之間解耦,就可以如下寫個簡單的

    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);
            }
        }
    }
}

 

 

相關文章