ABP EventBus(事件总线)

事件总线就是订阅/发布模式的一种实现    事件总线就是为了降低耦合

1.比如在winform中  到处都是事件 

触发事件的对象  sender

事件的数据    e

事件的处理逻辑  方法体

通过EventBus实现事件对象和处理逻辑的解耦

1.抽离事件对象    发生时间的事件   触发事件的对象源(可选)

1// 2 // 摘要: 3 // Defines interface for all Event data classes. 4 public interface IEventData 5 { 6 // 7 // 摘要: 8 // The time when the event occured. 9 DateTime EventTime { get; set; } 10 // 11 // 摘要: 12 // The object which triggers the event (optional). 13 object EventSource { get; set; }

 2.抽离事件的处理对象

1public interface IEventHandler 2 { 3 } 4 public interface IEventHandler<in TEventData> : IEventHandler 5 { 6 /// <summary> 7 /// Handler handles the event by implementing this method. 8 /// </summary> 9 /// <param name="eventData">Event data</param> 10 void HandleEvent(TEventData eventData); 11 }

3.所有EventData跟EventHandler不再耦合  全都跟EventBus进行通信

 在EventBus中有一个字典进行存放 EventData类型跟需要触发的Handler对象   

这里的Type就是EventData       List<IEventHandlerFactory>>就是存放处理当前EventData的多个Handler

private readonly ConcurrentDictionary<Type, List<IEventHandlerFactory>> _handlerFactories;

4.ABP的EventBus封装的比较高深     自己来个简洁版    思想是一样的(这里还存在很多问题   比如并发  往字典存放数据没有加锁等问题  具体的看ABP)

ABP初始化的时候会把所有的EventData和EventHandler对应存放到字典中   也可以通过Unregister移除某一个Handler

1public class EventBus : IEventBus 2 { 3 public EventBus() 4 { 5 mapDic = new ConcurrentDictionary<Type, List<Type>>(); 6 } 7 //EventBus单例模式 8 public static EventBus Default = new EventBus(); 9 //存储EventData和EventHandle的映射关系(没有存放handler的实例而是存放metaData,然后通过反射调用) 10 private ConcurrentDictionary<Type, List<Type>> mapDic; 11 12 public void Register<TEventData>(Type handlerType) where TEventData : IEventData 13 { 14 //将数据存储到mapDic 15 var dataType = typeof(TEventData); 16 Register(dataType, handlerType); 17 } 18 19 public void Register(Type eventType, Type handlerType) 20 { 21 if (mapDic.Keys.Contains(eventType)) 22 { 23 if (!mapDic[eventType].Contains(handlerType)) 24 { 25 mapDic[eventType].Add(handlerType); 26 } 27 } 28 else 29 { 30 mapDic[eventType] = new List<Type>() { handlerType }; 31 } 32 } 33 34 public void Unregister<TEventData>(Type handler) where TEventData : IEventData 35 { 36 var dataType = typeof(TEventData); 37 Unregister(dataType, handler); 38 } 39 40 public void Unregister(Type eventType, Type handlerType) 41 { 42 if (mapDic.Keys.Contains(eventType)) 43 { 44 if (mapDic[eventType].Contains(handlerType)) 45 { 46 mapDic[eventType].Remove(handlerType); 47 } 48 } 49 } 50 51 public void Trigger<TEventData>(TEventData eventData) where TEventData : IEventData 52 { 53 var dataType = eventData.GetType(); 54 //获取当前的EventData绑定的所有Handler 55 var handlerTypes = mapDic[dataType]; 56 foreach (var handlerType in handlerTypes) 57 { 58 var methodInfo = handlerType.GetMethod("EventHandle"); 59 if (methodInfo != null) 60 { 61 // var handler = Assembly.GetExecutingAssembly().CreateInstance(handlerType.FullName); 62 var handler = Activator.CreateInstance(handlerType); 63 //执行所有的Handler方法 64 methodInfo.Invoke(handler, new object[] { eventData }); 65 } 66 } 67 } 68 }

提供了EventData和Handler的绑定    也可以移除指定的Handler   

通过调用.Trigger()    然后当前的EventData类型在字典中找到当前类型的所有Handler   执行所有Handler的处理方法

事件总线通过 EventBusInstaller 来注册 EventBus 和监听事件。 每当IocContainer注册一个类型后 会判断当前类型是否实现IEventHandler   获取具体的EventData类型在EventBus上进行注册

1private void Kernel_ComponentRegistered(string key, IHandler handler) 2 { 3 /* This code checks if registering component implements any IEventHandler<TEventData> interface, if yes, 4 * gets all event handler interfaces and registers type to Event Bus for each handling event. 5 */ 6 if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(handler.ComponentModel.Implementation)) 7 { 8 return; 9 } 10 11 var interfaces = handler.ComponentModel.Implementation.GetTypeInfo().GetInterfaces(); 12 foreach (var @interface in interfaces) 13 { 14 if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) 15 { 16 continue; 17 } 18 19 var genericArgs = @interface.GetGenericArguments(); 20 if (genericArgs.Length == 1) 21 { 22 _eventBus.Register(genericArgs[0], new IocHandlerFactory(_iocResolver, handler.ComponentModel.Implementation)); 23 } 24 } 25 }

在ABP中使用EventBus

1.定义自己的数据对象

1public class MyEventData : EventData 2 { 3 public string Name { get; set; } 4 }

2.定义自己的处理事件Handler

1public class MyEventHandler : IEventHandler<MyEventData>, ITransientDependency 2 { 3 public ILogger Logger { set; get; } 4 public MyEventHandler() 5 { 6 Logger = NullLogger.Instance; 7 } 8 public void HandleEvent(MyEventData eventData) 9 { 10 Logger.Info($"这是{eventData.Name}自定义的HandEvent处理事件"); 11 } 12 }

3.通过属性注入 或者构造函数注入 或者直接用静态实例

1public class TaskAppService : ApplicationService 2{ 3 public IEventBus EventBus { get; set; } 4 5 public TaskAppService() 6 { 7 EventBus = NullEventBus.Instance; 8 } 9 10 public void CompleteTask(CompleteTaskInput input) 11 { 12 EventBus.Trigger(new MyEventData {Name= "abc123"}); 13 } 14} 15 16EventBus.Default.Trigger(new MyEventData {Name= "abc123"});

https://www.cnblogs.com/myzony/p/9413351.html

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Apache Synapse 远程代码执行漏洞(CVE

!(https://oscimg.oschina.net/oscnet/435fc4cde65d4aee9a2efca3080cb89e.png)0x00事件背景ApacheSynapse是一个简单、轻量级的高性能企业服务总线(ESB),它是在ApacheSoftwareFoun

Guava — EventBus

Guava提供了事件总线的一个实现方案EventBus。它是事件发布订阅模式的实现,观察者模式。Guava为我们提供了同步实现EventBus和异步实现AsyncEventBus两个事件总线,他们都不是单例的eventBus.post(1);eventBus.post(1L);post方法,直接发布事件订阅者需要注册进来,ev