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