中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Lind.DDD.Events事件總線~自動化注冊

回到目錄

讓大叔興奮的自動化注冊

對于領域事件之前說過,在程(cheng)序啟動時訂(ding)閱(注冊)一(yi)(yi)些(xie)事(shi)件處理程(cheng)序,然(ran)后在程(cheng)序的(de)(de)(de)具體(ti)位置去發布(觸(chu)發)它(ta),這是傳統的(de)(de)(de)pub/sub模式的(de)(de)(de)體(ti)現,當然(ran)也沒(mei)有(you)什么問題,為(wei)了讓(rang)它(ta)支持分布式的(de)(de)(de)場景,我們引用了redis這種存儲介(jie)質,這一(yi)(yi)切都早已,對些(xie)沒(mei)什么好(hao)說的(de)(de)(de),而今天的(de)(de)(de)重點(dian)在于"事(shi)件的(de)(de)(de)自(zi)動過(guo)注冊"的(de)(de)(de)理念,這個概念真(zhen)實在ABP架構(gou)(gou)中出現了,大(da)叔覺(jue)得(de)很不錯(cuo),所(suo)以(yi)也集成到了自(zi)己(ji)的(de)(de)(de)架構(gou)(gou)中,為(wei)些(xie)也興奮了一(yi)(yi)段時間,其中有(you)解(jie)決問題的(de)(de)(de)

Redis只是一種分布式(shi)存儲介質

對于第一版將事(shi)(shi)件總線放到內存的(de)(de)(de)情況(kuang)來(lai)說,使(shi)用(yong)(yong)redis這種存儲(chu)介質確實解(jie)決了分布式的(de)(de)(de)事(shi)(shi)件問題,它可以在更多場合下使(shi)用(yong)(yong),不用(yong)(yong)考慮WEB端的(de)(de)(de)負(fu)載均衡(heng),不用(yong)(yong)考慮服務端的(de)(de)(de)存儲(chu)壓力(li),不用(yong)(yong)考慮并發時的(de)(de)(de)吞(tun)吐量(liang),確實,redis是個存儲(chu)效率非常高的(de)(de)(de)產物,大(da)叔redis里(li)的(de)(de)(de)事(shi)(shi)件的(de)(de)(de)Key采用(yong)(yong)了當前EventData的(de)(de)(de)名(ming)字加上自定(ding)義的(de)(de)(de)前綴,這樣可以同時在多個項(xiang)目(mu)中使(shi)用(yong)(yong).

     /// <summary>
        /// 對于(yu)事(shi)件數(shu)據(ju)的存儲,目(mu)前采(cai)用內存字典
        /// </summary>
        private readonly IRedisClient _redisClient = RedisManager.GetClient();
        /// <summary>
        /// redis事件總線的Key
        /// </summary>
        private string redisKey = ConfigConstants.ConfigManager.Config.DomainEvent.RedisKey;
        /// <summary>
        /// 得到當前redis-eventbus-key
        /// </summary>
        /// <typeparam name="TEvent"></typeparam>
        /// <returns></returns>
        private string GetCurrentRedisKey<TEvent>()
        {
            return redisKey + "_" + typeof(TEvent).FullName;
        }
        /// <summary>
        ///得到(dao)非泛型版本的值(zhi)
        /// </summary>
        /// <param name="tEvent"></param>
        /// <returns></returns>
        private string GetCurrentRedisKey(Type tEvent)
        {
            return redisKey + "_" + tEvent.FullName;
        }

結構圖

主(zhu)角是SubscribeAll這個方法

對于當前應用程序下的(de)所(suo)有DLL進行(xing)反(fan)射,拿到所(suo)有實現了IEventHandler的(de)類型,然后對這么類型(事件處理程序)進行(xing)注冊即可.

核心代碼(Memory版):

     /// <summary>
        /// 需要過濾的接口(kou)
        /// </summary>
        string[] Excepts = { "IEventHandler`1", "ActionDelegatedEventHandler`1" };
        /// <summary>
        /// 全局(ju)統一注冊所有事件處(chu)理程(cheng)序,實現了IEventHandlers的
        /// </summary>
        public void SubscribeAll()
        {
            var types = AppDomain.CurrentDomain.GetAssemblies()
                  .SelectMany(a => a.GetTypes()
                  .Where(t => t.GetInterfaces().Contains(typeof(IEventHandlers))))
                  .Where(i => !Excepts.Contains(i.Name))
                  .ToArray();

            foreach (var item in types)
            {
                if (!item.ContainsGenericParameters)
                {
                    var en = Activator.CreateInstance(item);
                    foreach (var t in item.GetInterfaces().Where(i => i.Name != "IEventHandlers"))
                    {
                        Subscribe(t, en);
                    }
                }
            }
        }
        /// <summary>
        /// 訂閱非泛型版(ban)
        /// </summary>
        /// <param name="type"></param>
        /// <param name="eventHandler"></param>
        void Subscribe(Type type, object eventHandler)
        {
            lock (_objLock)
            {
                var eventType = type.GetGenericArguments()[0];
                //var eventType = type.GetType().GenericTypeArguments[0];
                if (_eventHandlers.ContainsKey(eventType))
                {
                    var handlers = _eventHandlers[eventType];
                    if (handlers != null)
                    {
                        if (!handlers.Exists(deh => _eventHandlerEquals(deh, eventHandler)))
                            handlers.Add(eventHandler);
                    }
                    else
                    {
                        handlers = new List<object>();
                        handlers.Add(eventHandler);
                    }
                }
                else
                    _eventHandlers.Add(eventType, new List<object> { eventHandler });
            }
        }

對于這種(zhong)倉儲,在(zai)Redis里事實上是以(yi)二進(jin)制的格(ge)式存儲的,所以(yi)要(yao)求你的EventData和EventHandler需(xu)要(yao)標記為(wei)可序列化,我經過測試,對于Json序列化的方(fang)式,在(zai)進(jin)行(xing)發布時(shi),不能成功回調"訂閱"的代(dai)碼(ma),原(yuan)因我目前還不清楚(chu),需(xu)要(yao)大家一起去研究!

 

感謝各位的閱讀!

回到目錄

posted @ 2016-06-12 16:00  張占嶺  閱讀(1898)  評論(0)    收藏  舉報