编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> 领域驱动设计 -> Lind.DDD.Events事件总线~自动化注册 -> 正文阅读

[领域驱动设计]Lind.DDD.Events事件总线~自动化注册

回到目录
让大叔兴奋的自动化注册
对于领域事件之前说过,在程序启动时订阅(注册)一些事件处理程序,然后在程序的具体位置去发布(触发)它,这是传统的pub/sub模式的体现,当然也没有什么问题,为了让它支持分布式的场景,我们引用了redis这种存储介质,这一切都早已集成到了Lind.DDD架构中,对些没什么好说的,而今天的重点在于"事件的自动过注册"的理念,这个概念真实在ABP架构中出现了,大叔觉得很不错,所以也集成到了自己的架构中,为些也兴奋了一段时间,其中有解决问题的
Redis只是一种分布式存储介质
对于第一版将事件总线放到内存的情况来说,使用redis这种存储介质确实解决了分布式的事件问题,它可以在更多场合下使用,不用考虑WEB端的负载均衡,不用考虑服务端的存储压力,不用考虑并发时的吞吐量,确实,redis是个存储效率非常高的产物,大叔redis里的事件的Key采用了当前EventData的名字加上自定义的前缀,这样可以同时在多个项目中使用.

     /// <summary>
        /// 对于事件数据的存储,目前采用内存字典
        /// </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>
        ///得到非泛型版本的值
        /// </summary>
        /// <param name="tEvent"></param>
        /// <returns></returns>
        private string GetCurrentRedisKey(Type tEvent)
        {
            return redisKey + "_" + tEvent.FullName;
        }

结构图


主角是SubscribeAll这个方法
对于当前应用程序下的所有DLL进行反射,拿到所有实现了IEventHandler的类型,然后对这么类型(事件处理程序)进行注册即可.
核心代码(Memory版):

     /// <summary>
        /// 需要过滤的接口
        /// </summary>
        string[] Excepts = { "IEventHandler`1", "ActionDelegatedEventHandler`1" };
        /// <summary>
        /// 全局统一注册所有事件处理程序,实现了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>
        /// 订阅非泛型版
        /// </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 });
            }
        }

对于这种仓储,在Redis里事实上是以二进制的格式存储的,所以要求你的EventData和EventHandler需要标记为可序列化,我经过测试,对于Json序列化的方式,在进行发布时,不能成功回调"订阅"的代码,原因我目前还不清楚,需要大家一起去研究!


感谢各位的阅读!
回到目录
  领域驱动设计 最新文章
领域驱动设计的基础知识总结
海西 · 云交付 DevOps实践落地方案
多服务器终端交互利器
《静儿的服务治理私房菜》服务治理和架构
服务治理概述
美团.点评服务治理框架
ASP.NET Zero
1.领域驱动简介.2.领域.子域.限界上下文.3.
东麓庄园系统开发
东麓庄园系统开发
上一篇文章      下一篇文章      查看所有文章
加:2016-06-13 19:09:06  更:2017-05-16 03:47:05 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 日历 万年历 2019年11日历
2019-11-19 4:08:32
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识