剛做了一個EDA類庫,大家給看看

gameboyLV發表於2014-04-15
恩,本人對EDA類庫有幾個基本的需求:
1、支援POCO,訊息本身不能繼承父類,這樣利於序列化和遠端傳輸
2、不能使用字串作為訊息標識,這樣容易造成拼寫錯誤
3、訊息訂閱和釋出要儘量簡單,易於使用

// 在此輸入C程式碼
        //訂閱訊息
        CFMessage.Command.Subscribe((PasswordChanged d) => Debug.WriteLine(d.UserName));
        //釋出訊息
        CFMessage.Command.Publish(new PasswordChanged("zhangs", "123456", "654321"));
<p class="indent">


// 在此輸入C程式碼
    /// <summary>
    /// 訊息管理
    /// </summary>
    public static class CFMessage
    {
        private static Dictionary<string, ICFMessagePublisher> endpoints = new Dictionary<string, ICFMessagePublisher>();
        private static object endpointsLocker = new object();

        /// <summary>
        /// 獲取事件通道的訊息管理器
        /// </summary>
        /// <returns></returns>
        public static ICFMessagePublisher Event
        {
            get
            {
                return GetInstance("Event");
            }
        }
        /// <summary>
        /// 獲取命令通道的訊息管理器
        /// </summary>
        /// <returns></returns>
        public static ICFMessagePublisher Command
        {
            get
            {
                return GetInstance("Command");
            }
        }
        /// <summary>
        /// 獲得指定通道的訊息管理器
        /// </summary>
        /// <param name="endpoint">訊息通道</param>
        /// <returns></returns>
        public static ICFMessagePublisher GetInstance(string endpoint)
        {
            if (!endpoints.ContainsKey(endpoint))
            {
                lock (endpointsLocker)
                {
                    if (!endpoints.ContainsKey(endpoint))
                        endpoints.Add(endpoint, new CFMessagePublisher());
                }
            }
            return endpoints[endpoint];
        }

    }
<p class="indent">


// 在此輸入C程式碼
    /// <summary>
    /// 訊息釋出管理
    /// </summary>
    internal class CFMessagePublisher : ICFMessagePublisher
    {
        private Dictionary<Type, List<CFMessageSubscriber>> subscribers = new Dictionary<Type, List<CFMessageSubscriber>>();
        private object subscribersLocker = new object();
        /// <summary>
        /// 訂閱同步訊息
        /// </summary>
        /// <typeparam name="T">訊息型別</typeparam>
        /// <param name="domainEventSubscriber">訊息響應</param>
        public void Subscribe<T>(Action<T> domainEventSubscriber)
        {
            this.Subscribe(new CFMessageSubscriber
            {
                EventType = typeof(T),
                EventHandler = domainEventSubscriber,
                IsAsnyc = false,
            });
        }
        /// <summary>
        /// 訂閱非同步訊息
        /// </summary>
        /// <typeparam name="T">訊息型別</typeparam>
        /// <param name="domainEventSubscriber">訊息響應</param>
        public void SubscribeAsync<T>(Action<T> domainEventSubscriber)
        {
            this.Subscribe(new CFMessageSubscriber
            {
                EventType = typeof(T),
                EventHandler = domainEventSubscriber,
                IsAsnyc = true,
            });
        }
        /// <summary>
        /// 訂閱訊息
        /// </summary>
        /// <param name="domainEventSubscriber">訊息響應</param>
        private void Subscribe(CFMessageSubscriber domainEventSubscriber)
        {
            if (!this.subscribers.ContainsKey(domainEventSubscriber.EventType))
            {
                lock (this.subscribersLocker)
                {
                    if (!this.subscribers.ContainsKey(domainEventSubscriber.EventType))
                        this.subscribers.Add(domainEventSubscriber.EventType, new List<CFMessageSubscriber>());
                }
            }
            this.subscribers[domainEventSubscriber.EventType].Add(domainEventSubscriber);
        }

        /// <summary>
        /// 釋出訊息
        /// </summary>
        /// <typeparam name="T">訊息型別</typeparam>
        /// <param name="domainEvent">訊息體</param>
        public void Publish<T>(T domainEvent)
        {
            List<CFMessageSubscriber> subscriber = null;
            this.subscribers.TryGetValue(typeof(T), out subscriber);
            if (subscriber != null)
            {
                subscriber.ForEach(d =>
                {
                    Action<T> action = (Action<T>)d.EventHandler;
                    if (d.IsAsnyc)
                        action.BeginInvoke(domainEvent, ar =>
                        {
                            try { action.EndInvoke(ar); }
                            catch { }
                        }, null);
                    else
                        action.Invoke(domainEvent);
                });
            }
        }

        /// <summary>
        /// 重置訊息訂閱佇列
        /// </summary>
        public void Reset()
        {
            this.subscribers.Clear();
        }
        /// <summary>
        /// 重置指定型別的訊息訂閱佇列
        /// </summary>
        /// <typeparam name="T">訊息型別</typeparam>
        public void Reset<T>()
        {
            Type type = typeof(T);
            if (this.subscribers.ContainsKey(type))
                this.subscribers.Remove(type);
        }

    }
<p class="indent">


// 在此輸入C程式碼
    /// <summary>
    /// 訊息訂閱管理
    /// </summary>
    public class CFMessageSubscriber
    {
        /// <summary>
        /// 訊息型別
        /// </summary>
        public Type EventType { get; set; }
        /// <summary>
        /// 訊息響應
        /// </summary>
        public Delegate EventHandler { get; set; } 
        /// <summary>
        /// 是否非同步響應
        /// </summary>
        public bool IsAsnyc { get; set; }
    }
<p class="indent">

相關文章