DDD領域驅動之乾貨(四)補充篇!

距離上一篇DDD系列完結已通過了很長一段時間,項目也擱置了一段時間,想一想仍是繼續完善下去。html

DDD領域驅動之乾貨(三)完結篇!

上一篇說到了如何實現uow配合Repository在autofac和automapper下實現的功能,今天完善一下事件驅動也就是領域驅動。app

領域驅動的概念網上一搜一大推,我就不一一累贅,本文主要講解如何實現領域事件和事件總線。dom

事件一共提供三個方法去完成事件的實現-----------註冊事件、卸載事件、發佈事件異步

那麼在註冊事件的時候咱們怎麼樣是定義一個事件呢?ide

以下圖:post

圖中的Events爲事件,handler爲事件的處理,bus爲事件總線。url

這麼一來思路就清晰多了。spa

首先咱們爲事件定義一個標識事件的接口。3d

public interface IEvent
    {

        // 獲取產生事件的時間
        DateTime Time { get; set; }
        //事件源
        object Source { get; set; }

    }

全部的事件類都應該實現該接口。code

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

代碼上我都有註釋,過多了我就很少作說明。

以上就是我對領域事件和領域總線的理解,歡迎大佬指正。

相關文章
相關標籤/搜索