| |
|
![]() |
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教程 经验交流 |
-> 领域驱动设计 -> [Architect] Abp 框架原理解析(2) EventBus -> 正文阅读 |
[领域驱动设计][Architect] Abp 框架原理解析(2) EventBus |
本节目录 原理介绍 Abp源码分析 代码实现 原理介绍 事件总线大致原理: (1) 在事件总线内部维护着一个事件与事件处理程序相映射的字典。 (2) 利用反射,事件总线会将实现了IEventHandler的处理程序与相应事件关联到一起,相当于实现了事件处理程序对事件的订阅。 (3) 当发布事件时,事件总线会从字典中找出相应的事件处理程序,然后利用反射去调用事件处理程序中的方法。 Abp源码分析 1.AbpKernelModule的Initialize方法 ![]() 2.EventBusInstaller的Install方法 ![]() 3.Kernel_ComponentRegistered ![]() 以上将事件注册完成了. 剩下就需要如何触发了. 触发实际上是写在代码里的,最终调用的其实还是EventBus.Trigger() ![]() 代码实现 看完Abp的实现,关键点还是反射以及IoC注册对象事件的拦截. 先上实现效果: interface IPerson { void Say(); } class Person : IPerson { public IEventBus EventBus { get; set; } public void Say() { var str = "Say"; Console.WriteLine(str); EventBus.Trigger(typeof(SayEventData), this, new SayEventData() { Content = str }); } } 定义上面需要的EventData,实际这是事件基类. [Serializable] public abstract class EventData : IEventData { public DateTime EventTime { get; set; } /// <summary> /// The object which triggers the event (optional). /// </summary> public object EventSource { get; set; } protected EventData() { EventTime = DateTime.Now; } } public interface IEventData { DateTime EventTime { get; set; } object EventSource { get; set; } } 自定义事件,继承事件基类,可以添加事件需要传递的数据. public class SayEventData : EventData { public string Content { get; set; } } 定义IEventHandle,实际这是事件处理程序,一个事件一般对应多个事件处理程序. public interface IEventHandler { } public interface IEventHandler<in TEventData> : IEventHandler { /// <summary> /// Handler handles the event by implementing this method. /// </summary> /// <param name="eventData">Event data</param> void HandleEvent(TEventData eventData); } 自定义的EventHandle,各种事件订阅器. public class SayEvent : IEventHandler<SayEventData> { public void HandleEvent(SayEventData eventData) { Console.WriteLine("进入事件啦:" + eventData.Content); } } 事件总线EventBus,管理事件的中心.可以细化接口. public interface IEventBus { void Register(Type eventType, IEventHandler handler); void Trigger(Type eventType, object eventSource, IEventData eventData); } EventBus实现,核心是反射调用事件处理程序. public class EventBus : IEventBus { public static EventBus Default { get { return DefaultInstance; } } private static readonly EventBus DefaultInstance = new EventBus(); private readonly Dictionary<Type, List<IEventHandler>> _eventHandlers; public EventBus() { _eventHandlers = new Dictionary<Type, List<IEventHandler>>(); } public void Register(Type eventType, IEventHandler handler) { GetOrCreateHandlerFactories(eventType).Add(handler); } private List<IEventHandler> GetOrCreateHandlerFactories(Type eventType) { List<IEventHandler> handlers; if (!_eventHandlers.TryGetValue(eventType, out handlers)) { _eventHandlers[eventType] = handlers = new List<IEventHandler>(); } return handlers; } public void Trigger(Type eventType, object eventSource, IEventData eventData) { eventData.EventSource = eventSource; var handles = GetOrCreateHandlerFactories(eventType); if (handles.Count > 0) { foreach (var eventHandler in handles) { if (eventHandler == null) { throw new Exception("Registered event handler for event type " + eventType.Name + " does not implement IEventHandler<" + eventType.Name + "> interface!"); } //eventHandler. var handlerType = typeof(IEventHandler<>).MakeGenericType(eventType); handlerType .GetMethod("HandleEvent", BindingFlags.Public | BindingFlags.Instance, null, new[] { eventType }, null) .Invoke(eventHandler, new object[] { eventData }); } } } } 执行,来测试是否通了. private static IEventBus _eventBus; static void Main(string[] args) { var container = IocManager.Instance.IocContainer; container.Register(Component.For<IEventBus>().Instance(EventBus.Default)); _eventBus = container.Resolve<IEventBus>(); container.Kernel.ComponentRegistered += Kernel_ComponentRegistered; //在Abp中,由于注册了所有ITransientDependency,所以这2个不需要手动注册 container.Register(Component.For<Person, IPerson>()); container.Register(Component.For<IEventHandler<SayEventData>, SayEvent>()); container.Resolve<IPerson>().Say(); Console.ReadKey(); } 注册事件的绑定 private static void Kernel_ComponentRegistered(string key, IHandler handler) { if (!typeof(IEventHandler).IsAssignableFrom(handler.ComponentModel.Implementation)) { return; } var interfaces = handler.ComponentModel.Implementation.GetInterfaces(); foreach (var @interface in interfaces) { if (!typeof(IEventHandler).IsAssignableFrom(@interface)) { continue; } var genericArgs = @interface.GetGenericArguments(); if (genericArgs.Length == 1) { //_eventBus.Register(genericArgs[0], handler.ComponentModel.Implementation.CreateInstance<IEventHandler>()); _eventBus.Register(genericArgs[0], (IEventHandler)IocManager.Instance.IocContainer.Resolve(handler.ComponentModel.Implementation)); } } } 至此,事件成功执行 ![]() 本文地址:http://www.cnblogs.com/neverc/p/5254859.html |
领域驱动设计 最新文章 |
领域驱动设计的基础知识总结 |
海西 · 云交付 DevOps实践落地方案 |
多服务器终端交互利器 |
《静儿的服务治理私房菜》服务治理和架构 |
服务治理概述 |
美团.点评服务治理框架 |
ASP.NET Zero |
1.领域驱动简介.2.领域.子域.限界上下文.3. |
东麓庄园系统开发 |
东麓庄园系统开发 |
上一篇文章 下一篇文章 查看所有文章 |
|
360图书馆
软件开发资料
购物精选
新闻资讯
Chinese Culture
三丰软件
开发
中国文化
阅读网
日历
万年历
2019年12日历 2019-12-9 21:48:23 |
|
网站联系: qq:121756557 email:121756557@qq.com 编程知识 |