zoukankan      html  css  js  c++  java
  • DDD领域驱动之干货(四)补充篇!

    距离上一篇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;
        }
    View Code

    接口定义好了之后是实现接口。

            
    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
        }
    }
    View Code

    代码上我都有注释,过多了我就不多做说明。

    以上就是我对领域事件和领域总线的理解,欢迎大佬指正。

  • 相关阅读:
    boltdb 学习和实践
    解读-m addrtype --dst-type LOCAL -j DOCKER
    找到linux中当前java的安装位置
    java.library.path是什么?
    Linux 中【./】和【/】和【.】之间有什么区别?
    [SpringMVC]JSON乱码问题
    iOS MVVM的理解与分析
    iOS中为什么必须在主线程操作UI
    几种直播流媒体协议
    IOS硬编码
  • 原文地址:https://www.cnblogs.com/edna-lzh/p/7084658.html
Copyright © 2011-2022 走看看