成员介绍:

IEventBus、EventBus:事件总线

IEventHandler、xxxEventHandler:事件处理程序

IEvent、xxxEvent:事件,一个事件可对应多个事件处理程序

EventHandlerAttribute:事件处理程序的特性,可添加排序信息等

EvnetHandlerMetadata:IEventHandler信息

EventHandlerMetadataItem:EventHandler实例信息

事件总线:

  1. public interface IEventBus
  2. {
  3. void Trigger<TEvent>(TEvent eventData, string topic = null) where TEvent : IEvent;
  4. }
  5. public class EventBus : IEventBus
  6. {
  7. private static System.Collections.Concurrent.ConcurrentDictionary<Type, EvnetHandlerMetadata> _evnetHandlerMetadatas
  8. = new ConcurrentDictionary<Type, EvnetHandlerMetadata>();
  9. private static readonly EventHandlerAttribute DefaultAttribute = new EventHandlerAttribute()
  10. {
  11. IgnoreError = false,
  12. Priority = ,
  13. Topic = null
  14. };
  15.  
  16. static EventBus()
  17. { }
  18.  
  19. public Func<Type, object> Activator { get; set; }
  20.  
  21. /// <summary>
  22. /// 触发事件
  23. /// </summary>
  24. /// <typeparam name="IEvent"></typeparam>
  25. /// <param name="eventData"></param>
  26. public void Trigger<TEvent>(TEvent eventData, string topic = null) where TEvent : IEvent
  27. {
  28.  
  29. EvnetHandlerMetadata evnetHandlerMetadata = _evnetHandlerMetadatas.GetOrAdd(typeof(TEvent), (key) =>
  30. {
  31. var handlerType = typeof(IEventHandler<>).MakeGenericType(typeof(TEvent));
  32. var handlerMetadata = new EvnetHandlerMetadata()
  33. {
  34. EventHandlerType = handlerType,
  35. EventType = key,
  36. Items = new List<EventHandlerMetadataItem>()
  37. };
  38. var handlerInstances = Activator.Invoke(typeof(IEnumerable<>).MakeGenericType(handlerType)) as IEnumerable;
  39. foreach (var handlerInstance in handlerInstances)
  40. {
  41. var typeInfo = handlerInstance.GetType().GetTypeInfo();
  42. var handleMethods = typeInfo.DeclaredMethods.Where(t => t.Name.EndsWith($"{key.Name}>.Handle") || t.Name == "Handle");
  43. var method = handleMethods.FirstOrDefault();
  44. if (method == null) continue;
  45. var attr = method.GetCustomAttribute<EventHandlerAttribute>()
  46. ?? handlerInstance.GetType().GetCustomAttribute<EventHandlerAttribute>()
  47. ?? DefaultAttribute
  48. ;
  49. handlerMetadata.Items.Add(new EventHandlerMetadataItem()
  50. {
  51. Method = method,
  52. IgnoreError = attr.IgnoreError,
  53. Priority = attr.Priority,
  54. Type = handlerInstance.GetType()
  55. });
  56. }
  57. handlerMetadata.Items = handlerMetadata.Items.OrderByDescending(p => p.Priority).ThenBy(x => x.Type.Name).ToList();
  58. return handlerMetadata;
  59. });
  60.  
  61. var handlers = evnetHandlerMetadata.Items
  62. .WhereIf(p => p.Topic == topic, !string.IsNullOrEmpty(topic))
  63. .Select(x => new { Instance = Activator.Invoke(x.Type), Meta = x })
  64. .ToList()
  65. ;
  66. foreach (var handler in handlers)
  67. {
  68. try
  69. {
  70. handler.Meta.Method.Invoke(handler.Instance, new object[] { eventData });
  71. }
  72. catch (Exception ex)
  73. {
  74. if (!handler.Meta.IgnoreError)
  75. {
  76. while (true)
  77. {
  78. if (ex.InnerException == null)
  79. {
  80. throw ex;
  81. }
  82. else
  83. {
  84. ex = ex.InnerException;
  85. }
  86. }
  87.  
  88. }
  89. }
  90. }
  91. }
  92.  
  93. public class EventHandlerMetadataItem
  94. {
  95. public Type Type { get; set; }
  96. public MethodInfo Method { get; set; }
  97. public int Priority { get; set; }
  98. public bool IgnoreError { get; set; }
  99. public string Topic { get; set; }
  100.  
  101. }
  102.  
  103. public class EvnetHandlerMetadata
  104. {
  105. public List<EventHandlerMetadataItem> Items { get; set; }
  106. public Type EventHandlerType { get; set; }
  107. public Type EventType { get; set; }
  108.  
  109. }
  110. }

事件处理接口:

  1. /// <summary>
  2. /// 事件处理接口
  3. /// </summary>
  4. /// <typeparam name="TEvent">继承IEvent对象的事件源对象</typeparam>
  5. public interface IEventHandler<T> where T : IEvent
  6. {
  7. /// <summary>
  8. /// 处理程序
  9. /// </summary>
  10. /// <param name="evt"></param>
  11. void Handle(T evt);
  12. }
  13.  
  14. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  15. public class EventHandlerAttribute : Attribute
  16. {
  17. /// <summary>
  18. /// 执行优先级
  19. /// </summary>
  20. public int Priority { get; set; }
  21. public bool IgnoreError { get; set; }
  22. public string Topic { get; set; }
  23. public EventHandlerAttribute()
  24. {
  25.  
  26. }
  27. }

public interface IEvent
{
}

具体事件处理:

  1. /// <summary>
  2. /// 文件上传事件处理
  3. /// </summary>
  4. [EventHandler(Priority =, IgnoreError = true)]
  5. public class FileUploadEventHandler : IEventHandler<FileUploadEvent>
  6. {
  7. private readonly IFeeService _feeService;
  8. private readonly ILogger _logger;
  9.  
  10. public FileUploadEventHandler(
  11. IFeeService feeService,
  12. ILogger<FileUploadEventHandler> logger
  13. )
  14. {
  15. _feeService = feeService;
  16. _logger = logger;
  17. }
  18.  
  19. public void Handle(FileUploadEvent evt)
  20. {
  21. // _logger.LogInformation(evt.FileName);
  22. ////扣减存储空间
  23. //var useResult=_feeService.UseFeeItem(Enums.Finance_FeeItem.Storage, evt.FileSize, $"上传文件{evt.FileName}");
  24. //if (!useResult.Success)
  25. //{
  26. // throw new Exception(useResult.Message);
  27. //}
  28. }
  29. }

事件触发:

  1. var eventBus = _serviceLocator.GetService<IEventBus>();
  2. eventBus.Trigger(new FileUploadEvent() { OwnUserID = globalValue.User.ID, UserID = globalValue.User.OwnUserID, Url = uploadResult.Data.Url, FileName = file.FileName, FileSize = file.Length, FileType = fileType });

参考:https://www.cnblogs.com/lwqlun/p/10468058.html

EventBus事件总线(牛x版)的更多相关文章

  1. Guava - EventBus(事件总线)

    Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们的模块和领域边界很好的解耦设计 ...

  2. EventBus(事件总线)

    EventBus(事件总线) Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们 ...

  3. dhroid - eventbus 事件总线

    你听过onClick 事件,onItemClick 事件,事件总线不一定听过吧, eventbus 事件总线也是一个编程思想,为什么要设计EventBus了,因为他是领域驱动设计中比不可少的模块,它承 ...

  4. EventBus事件总线

    EventBus事件总线的使用-自己实现事件总线   在C#中,我们可以在一个类中定义自己的事件,而其他的类可以订阅该事件,当某些事情发生时,可以通知到该类.这对于桌面应用或者独立的windows服务 ...

  5. EventBus 事件总线 案例

    简介 地址:https://github.com/greenrobot/EventBus EventBus是一个[发布 / 订阅]的事件总线.简单点说,就是两人[约定]好怎么通信,一人发布消息,另外一 ...

  6. C#总结(六)EventBus事件总线的使用-自己实现事件总线

    在C#中,我们可以在一个类中定义自己的事件,而其他的类可以订阅该事件,当某些事情发生时,可以通知到该类.这对于桌面应用或者独立的windows服务来说是非常有用的.但对于一个web应用来说是有点问题的 ...

  7. Android 开发 框架系列 EventBus 事件总线

    介绍 GitHub:https://github.com/greenrobot/EventBus 先聊聊EventBus 线程总线是干什么的,使用环境,优点.缺点. 干什么的? 一句话,简单统一数据传 ...

  8. EventBus 事件总线之我的理解

    用例:假设公司发布了一个公告 需要通过短信 和 邮件分别2种方式 通知员工 1:首先我们建立领域模型 /// <summary> /// 领域核心基类 /// </summary&g ...

  9. Orchard EventBus 事件总线及 IEventHandler作用

    事件总线接口定义: public interface IEventBus : IDependency { IEnumerable Notify(string messageName, IDiction ...

随机推荐

  1. MySQL实战45讲学习笔记:第三十五讲

    一.本节概述 在上一篇文章中,我和你介绍了 join 语句的两种算法,分别是 Index Nested-LoopJoin(NLJ) 和 Block Nested-Loop Join(BNL). 我们发 ...

  2. Harbor + Https 部署

    关闭防火墙和selinux systemctl stop firewalld sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/sysconfig/selin ...

  3. springboot项目POM文件第一行报错 Unknown Error

    改成 war 不错了,但是打包麻烦 pom 文件报错 UnKnown Error第一次碰到这个问题,花了几个小时才解决,除了UnKnown 没有任何提示.网上搜的大部分情况都不是我遇到的. 还是没有解 ...

  4. 基于OceanStor Dorado V3存储之精简高效 Smart 系列特性

    基于OceanStor Dorado V3存储之精简高效 Smart 系列特性 1.1  在线重删 1.2  在线压缩 1.3  智能精简配置 1.4  智能服务质量控制 1.5  异构虚拟化 1.6 ...

  5. RFC的远程调用-异步

    接上篇RFC的远程调用-同步(https://www.cnblogs.com/BruceKing/p/11169930.html). TABLES:USR21. DATA:A TYPE USR21-P ...

  6. 【机器学习笔记】来吧!解析k-NN

    序: 监督型学习与无监督学习,其最主要区别在于:已知的数据里面有没有标签(作为区别数据的内容). 监督学习大概是这个套路: 1.给定很多很多数据(假设2000个图片),并且给每个数据加上标签(与图片一 ...

  7. js函数定义及一些说明

    1.javascript定义函数的三种方法一.function语句//这个方法比较常用function fn(){ alert("这是使用function语句进行函数定义");}f ...

  8. background 设置文本框背景图

    background 属性的作用是给元素设置背景,它是一个复合属性,常用的子属性如下: background-color 指定元素的背景颜色. background-image 指定元素的背景图像. ...

  9. Python - 输入和输出 - 第十七天

    Python 输入和输出 在前面几个章节中,我们其实已经接触了 Python 的输入输出的功能.本章节我们将具体介绍 Python 的输入输出. 输出格式美化 Python两种输出值的方式: 表达式语 ...

  10. 从VisualStudio资源文件看.NET资源处理

    c# 工程里面,经常会添加资源文件. 作用: 一处文本多个地方的UI使用,最好把文本抽成资源,多处调用使用一处资源. 多语言版本支持,一份代码支持多国语言.配置多国语言的资源文件,调用处引用资源. 例 ...