成员介绍:

IEventBus、EventBus:事件总线

IEventHandler、xxxEventHandler:事件处理程序

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

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

EvnetHandlerMetadata:IEventHandler信息

EventHandlerMetadataItem:EventHandler实例信息

事件总线:

     public interface IEventBus
{
void Trigger<TEvent>(TEvent eventData, string topic = null) where TEvent : IEvent;
}
public class EventBus : IEventBus
{
private static System.Collections.Concurrent.ConcurrentDictionary<Type, EvnetHandlerMetadata> _evnetHandlerMetadatas
= new ConcurrentDictionary<Type, EvnetHandlerMetadata>();
private static readonly EventHandlerAttribute DefaultAttribute = new EventHandlerAttribute()
{
IgnoreError = false,
Priority = ,
Topic = null
}; static EventBus()
{ } public Func<Type, object> Activator { get; set; } /// <summary>
/// 触发事件
/// </summary>
/// <typeparam name="IEvent"></typeparam>
/// <param name="eventData"></param>
public void Trigger<TEvent>(TEvent eventData, string topic = null) where TEvent : IEvent
{ EvnetHandlerMetadata evnetHandlerMetadata = _evnetHandlerMetadatas.GetOrAdd(typeof(TEvent), (key) =>
{
var handlerType = typeof(IEventHandler<>).MakeGenericType(typeof(TEvent));
var handlerMetadata = new EvnetHandlerMetadata()
{
EventHandlerType = handlerType,
EventType = key,
Items = new List<EventHandlerMetadataItem>()
};
var handlerInstances = Activator.Invoke(typeof(IEnumerable<>).MakeGenericType(handlerType)) as IEnumerable;
foreach (var handlerInstance in handlerInstances)
{
var typeInfo = handlerInstance.GetType().GetTypeInfo();
var handleMethods = typeInfo.DeclaredMethods.Where(t => t.Name.EndsWith($"{key.Name}>.Handle") || t.Name == "Handle");
var method = handleMethods.FirstOrDefault();
if (method == null) continue;
var attr = method.GetCustomAttribute<EventHandlerAttribute>()
?? handlerInstance.GetType().GetCustomAttribute<EventHandlerAttribute>()
?? DefaultAttribute
;
handlerMetadata.Items.Add(new EventHandlerMetadataItem()
{
Method = method,
IgnoreError = attr.IgnoreError,
Priority = attr.Priority,
Type = handlerInstance.GetType()
});
}
handlerMetadata.Items = handlerMetadata.Items.OrderByDescending(p => p.Priority).ThenBy(x => x.Type.Name).ToList();
return handlerMetadata;
}); var handlers = evnetHandlerMetadata.Items
.WhereIf(p => p.Topic == topic, !string.IsNullOrEmpty(topic))
.Select(x => new { Instance = Activator.Invoke(x.Type), Meta = x })
.ToList()
;
foreach (var handler in handlers)
{
try
{
handler.Meta.Method.Invoke(handler.Instance, new object[] { eventData });
}
catch (Exception ex)
{
if (!handler.Meta.IgnoreError)
{
while (true)
{
if (ex.InnerException == null)
{
throw ex;
}
else
{
ex = ex.InnerException;
}
} }
}
}
} public class EventHandlerMetadataItem
{
public Type Type { get; set; }
public MethodInfo Method { get; set; }
public int Priority { get; set; }
public bool IgnoreError { get; set; }
public string Topic { get; set; } } public class EvnetHandlerMetadata
{
public List<EventHandlerMetadataItem> Items { get; set; }
public Type EventHandlerType { get; set; }
public Type EventType { get; set; } }
}

事件处理接口:

     /// <summary>
/// 事件处理接口
/// </summary>
/// <typeparam name="TEvent">继承IEvent对象的事件源对象</typeparam>
public interface IEventHandler<T> where T : IEvent
{
/// <summary>
/// 处理程序
/// </summary>
/// <param name="evt"></param>
void Handle(T evt);
} [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class EventHandlerAttribute : Attribute
{
/// <summary>
/// 执行优先级
/// </summary>
public int Priority { get; set; }
public bool IgnoreError { get; set; }
public string Topic { get; set; }
public EventHandlerAttribute()
{ }
}

public interface IEvent
{
}

具体事件处理:

     /// <summary>
/// 文件上传事件处理
/// </summary>
[EventHandler(Priority =, IgnoreError = true)]
public class FileUploadEventHandler : IEventHandler<FileUploadEvent>
{
private readonly IFeeService _feeService;
private readonly ILogger _logger; public FileUploadEventHandler(
IFeeService feeService,
ILogger<FileUploadEventHandler> logger
)
{
_feeService = feeService;
_logger = logger;
} public void Handle(FileUploadEvent evt)
{
// _logger.LogInformation(evt.FileName);
////扣减存储空间
//var useResult=_feeService.UseFeeItem(Enums.Finance_FeeItem.Storage, evt.FileSize, $"上传文件{evt.FileName}");
//if (!useResult.Success)
//{
// throw new Exception(useResult.Message);
//}
}
}

事件触发:

var eventBus = _serviceLocator.GetService<IEventBus>();
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

最新文章

  1. jQuery的$.ajax示例
  2. 在 github 上获取源码
  3. App架构设计经验谈:服务端接口的设计
  4. C++质因式分解
  5. careercup-树与图 4.7
  6. AFNetworking网络请求的get和post步骤
  7. 给Apache加载rewrite模块后,服务器返回500错误,以及a2enmod命令
  8. MUI 列表页面绑定接口数据
  9. nginx负载均衡2
  10. [LeetCode] Wildcard Matching 题解
  11. 设计模式——观察者模式(C++实现)
  12. js字符串操作总结
  13. Java的字符串分割的不同实现
  14. SCSS 在项目中的运用
  15. PS提亮户外儿童照
  16. node.js 基础三 消息推送
  17. Asp.Net Core2.0获取客户IP地址,及解决发布到Ubuntu服务器获取不到正确IP解决办法
  18. js对象的key类型
  19. Effective STL 学习笔记 31:排序算法
  20. Edge/Chrome/火狐/Safari/Opera和IE

热门文章

  1. MySQL实战45讲学习笔记:第三十三讲
  2. ReverseInteger:实现int整数的反转
  3. (二十五)golang--数组
  4. SQLyog 图形化数据库的操作教程
  5. 架构设计系列-前端模式的后端(BFF)翻译PhilCal&#231;ado
  6. JVM的监控工具之jconsole
  7. 【UOJ#82】【UR #7】水题生成器(贪心)
  8. CentOS7系统yum方式安装MySQL5.7
  9. WPF树形菜单--递归与非递归遍历生成树结构的集合
  10. cmd 运行bcp 提示:&#39;bcp&#39; 不是内部或外部命令,也不是可运行的程序 或批处理文件。