距离上一篇DDD系列完结已经过了很长一段时间,项目也搁置了一段时间,想想还是继续完善下去。
DDD领域驱动之干货(三)完结篇!
上一篇说到了如何实现uow配合Repository在autofac和automapper下实现的功能,今天完善一下事件驱动也就是领域驱动。
领域驱动的概念网上一搜一大推,我就不一一累赘,本文主要讲解如何实现领域事件和事件总线。
事件一共提供三个方法去完成事件的实现-----------注册事件、卸载事件、发布事件
那么在注册事件的时候我们怎么样是定义一个事件呢?
如下图:
图中的Events为事件,handler为事件的处理,bus为事件总线。
这么一来思路就清晰多了。
首先我们为事件定义一个标识事件的接口。
public interface IEvent { // 获取产生事件的时间 DateTime Time { get; set; } //事件源 object Source { get; set; } }
所有的事件类都应该实现该接口。
public class Event : IEvent { public DateTime Time { get; set; } public object Source { get; set; } public Event() { Time = DateTime.Now; } }
可以把这个Event看过是domianEvent的根事件,所有的领域事件应该继承根事件。
public class UserEvent :Event { public User info { get; set; } }
事件我们写完了,接下来是需要写事件要执行的处理。
/// <summary> /// 标志接口 /// </summary> public interface IHandler { } /// <summary> /// 事件处理器接口,所有事件处理器都要实现该接口。 /// </summary> public interface IEventHandler<TEvent> : IHandler where TEvent:IEvent { // 处理给定的事件 void Handle(TEvent Event); }
然后是写一个委托事件处理器。
public class ActionHandler<TEvent> : IEventHandler<TEvent> where TEvent : IEvent { public Action<TEvent> Action { get; private set; } public ActionHandler() { } public ActionHandler(Action<TEvent> handler) { Action = handler; } public void Handle(TEvent Event) { throw new NotImplementedException(); } }
处理事件的方法定义完成后,我们需要完成领域的处理。
public class UserHandler :IEventHandler<UserEvent> { public void Handle(UserEvent Event) { Event.Source = Event.info; } }
所有的事件我们定义完成后,接下来就是事件总线出场了。
public interface IEventBus { //注册事件 void RegisterAllHandler(IEnumerable<Assembly> assembles); void Register<THandle>(IHandler handle); void Register(Type eventType, Type handler); void Register<THandle>(Action<THandle> action) where THandle : IEvent; //反注册事件 void UnRegisiter<THandle>(Type handleType) where THandle : IEvent; void UnRegisterAllHandler<THandle>(); //触发事件 void TiggerEvent<THandle>(THandle eventData) where THandle : IEvent; void TiggerEvent<THandle>(Type eventHandlerType, THandle eventData) where THandle : IEvent; Task TiggerEventAsync<THandle>(THandle eventData) where THandle : IEvent; Task TiggerEventAsycn<THandle>(Type eventHandlerType, THandle eventData) where THandle : IEvent; }
接口定义好了之后是实现接口。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using KuRuMi.Mio.DoMain.Events.Events; using KuRuMi.Mio.DoMain.Events.Handler; using System.Reflection; using System.Collections.Concurrent; namespace KuRuMi.Mio.DoMain.Events.Bus { /// <summary> /// 事件总线 /// </summary> public class EventBus : IEventBus { private object locker = new object(); public static EventBus bus => new EventBus(); private static IEnumerable<Assembly> assemly { get; set; } private static readonly ConcurrentDictionary<Type, List<Type>> EventMapping = new ConcurrentDictionary<Type, List<Type>>(); /// <summary> /// 注册所有事件 /// </summary> /// <param name="assembles"></param> public void RegisterAllHandler(IEnumerable<Assembly> assembles) { assemly = assembles; foreach (Assembly assembly in assembles) { Type[] types = assembly.GetTypes(); foreach (Type type in types) { Type handlerInterfaceType = type.GetInterface("IEventHandler`1"); if (handlerInterfaceType != null) { Type eventType = handlerInterfaceType.GetGenericArguments()[0]; if (!EventMapping.Keys.Contains(eventType)) { Register(eventType, type); } } } } } /// <summary> /// 注册到事件总线 /// </summary> /// <param name="eventType"></param> /// <returns></returns> private List<Type> GetOrCreateHandlers(Type eventType) { return EventMapping.GetOrAdd(eventType, (type) => new List<Type>()); } #region 注册事件 /// <summary> /// 手动绑定事件 /// </summary> /// <typeparam name="THandle"></typeparam> /// <param name="handle"></param> public void Register<THandle>(IHandler handle) { Register(typeof(THandle), handle.GetType()); } public void Register(Type eventType, Type handler) { lock (locker) { GetOrCreateHandlers(eventType).Add(handler); } } /// <summary> /// 通过委托注册 /// </summary> /// <typeparam name="THandle"></typeparam> /// <param name="action"></param> public void Register<THandle>(Action<THandle> action) where THandle : IEvent { ActionHandler<THandle> ActionHandler = new ActionHandler<THandle>(action); Register<THandle>(ActionHandler); } #endregion #region 卸载事件 /// <summary> /// 手动卸载单个事件 /// </summary> /// <typeparam name="THandle"></typeparam> /// <param name="handleType"></param> public void UnRegisiter<THandle>(Type handleType) where THandle : IEvent { lock (locker) { GetOrCreateHandlers(typeof(THandle)).RemoveAll(t => t == handleType); } } /// <summary> /// 卸载所有事件 /// </summary> /// <typeparam name="THandle"></typeparam> public void UnRegisterAllHandler<THandle>() { lock (locker) { GetOrCreateHandlers(typeof(THandle)).Clear(); } } #endregion #region 触发事件 /// <summary> /// 根据事件源触发事件 /// </summary> /// <typeparam name="THandle"></typeparam> /// <param name="eventData"></param> public void TiggerEvent<THandle>(THandle eventData) where THandle : IEvent { //获取所有的事件处理 List<Type> handlerTypes = GetOrCreateHandlers(typeof(THandle)); if (handlerTypes != null && handlerTypes.Count > 0) { foreach (var handlerType in handlerTypes) { var handlerInterface = handlerType.GetInterface("IEventHandler`1"); foreach (Assembly assembly in assemly) { Type[] types = assembly.GetTypes(); foreach (Type type in types) { Type handlerInterfaceType = type.GetInterface("IEventHandler`1"); if (handlerInterfaceType != null) { //判断两个类型是否相等 if (handlerInterface == handlerInterfaceType) { var eventType = handlerInterfaceType.GenericTypeArguments[0]; EventMapping[eventType].ForEach(s=> { var obj = Activator.CreateInstance(s) as IEventHandler<THandle>; obj?.Handle(eventData); }); } } } } } } } /// <summary> /// 指定handler触发事件 /// </summary> /// <typeparam name="THandle"></typeparam> /// <param name="eventData"></param> /// <returns></returns> public void TiggerEvent<THandle>(Type eventHandlerType, THandle eventData) where THandle : IEvent { var handlerInterface = eventHandlerType.GetInterface("IEventHandler`1"); foreach (Assembly assembly in assemly) { Type[] types = assembly.GetTypes(); foreach (Type type in types) { Type handlerInterfaceType = type.GetInterface("IEventHandler`1"); if (handlerInterfaceType != null) { //判断两个类型是否相等 if (handlerInterface == handlerInterfaceType) { var eventType = handlerInterfaceType.GenericTypeArguments[0]; EventMapping[eventType].ForEach(s => { var obj = Activator.CreateInstance(s) as IEventHandler<THandle>; obj?.Handle(eventData); }); } } } } } /// <summary> /// 根据事件源触发事件(异步) /// </summary> /// <typeparam name="THandle"></typeparam> /// <param name="eventData"></param> /// <returns></returns> public Task TiggerEventAsync<THandle>(THandle eventData) where THandle : IEvent { return Task.Run(() => TiggerEvent<THandle>(eventData)); } /// <summary> /// 指定handler触发事件(异步) /// </summary> /// <typeparam name="THandle"></typeparam> /// <param name="eventHandlerType"></param> /// <param name="eventData"></param> /// <returns></returns> public Task TiggerEventAsycn<THandle>(Type eventHandlerType, THandle eventData) where THandle : IEvent { return Task.Run(() => TiggerEvent<THandle>(eventHandlerType, eventData)); } #endregion } }
代码上我都有注释,过多了我就不多做说明。
以上就是我对领域事件和领域总线的理解,欢迎大佬指正。
时间: 2024-10-12 02:26:56