<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      DDD~領域事件與事件總線

      回到目錄

      談談它

      終于有些眉目了,搜刮了很多牛人的資料,英文的,中文的,民國文的,終于小有成就了,同時也做了個DEMO,領域事件這東西好,但需要你明白它之后才會說好,而對于明白領域事件這件事來說,它的門檻有點高,居然花了我三天的時間才把它搞定,嗨!

      占占給它的定義

      領域事件:Domain Event,是針對某個業務來說的,或者說針對某個聚合的業務來說的,例如訂單生成這種業務,它可以同時對應一種事件,比如叫做OrderGeneratorEvent,而你的零散業務可能隨時會變,加一些業務,減一些業務,而對于訂單生成這個事件來說,它是唯一不變的,而我們需要把這些由產生訂單而發生變化的事情拿出來,而拿出來的這些業務就叫做"領域事件".其中的領域指的就是訂單生成這個聚合;而事件指的就是那些零散業務的統稱.

      它的主要幾個抽象

      在面向對象的編程世界里,做這種事情我們需要幾個抽象:

      領域對象事件標示:(標示接口,接口的一種,用來約束一批對象)IEvent

      領域對象的處理方法,行為:(需要讓那些零散的模塊重寫的方法,起個聽起來熟悉的名字,叫它handle吧)IEventHandler=>Handle

      事件總線:事件處理核心類,承載了事件的發布,訂閱與取消訂閱的邏輯,EventBus

      某個領域對象:為了實現某個業務,而創建的實體類,它里面有事件所需要的數據,它繼承了IEvent

      某個領域對象的事件:它是一個事件處理類,它實現了IEventHandler,它所處理的事情需要在Handle里去完成

      我的Demo的實現

      一 結果圖:

      二 核心類:

      IEvent接口,標示接口往往都是空的,呵呵

          /// <summary>
          /// 事件實體基類
          /// </summary>
          public interface IEvent
          {
          }

      IEventHandler接口,只有一個行為方法Handle

          /// <summary>
          /// 事件處理接口
          /// </summary>
          /// <typeparam name="TEvent">繼承IEvent對象的事件源對象</typeparam>
          public interface IEventHandler<TEvent>
              where TEvent : IEvent
          {
              /// <summary>
              /// 處理程序
              /// </summary>
              /// <param name="evt"></param>
              void Handle(TEvent evt);
      
          }

      EventBus是實現事件的核心,在這版里,它支持異步事件機制,使用Task實現,所以它需要運行在.net4.5平臺之上

         /// <summary>
          /// 事件總線
          /// 發布與訂閱處理邏輯
          /// 核心功能代碼
          /// </summary>
          public class EventBus
          {
              private EventBus() { }
      
              private static EventBus _eventBus = null;
              private readonly object sync = new object();
              /// <summary>
              /// 對于事件數據的存儲,目前采用內存字典
              /// </summary>
              private static Dictionary<Type, List<object>> eventHandlers = new Dictionary<Type, List<object>>();
              /// <summary>
              // checks if the two event handlers are equal. if the event handler is an action-delegated, just simply
              // compare the two with the object.Equals override (since it was overriden by comparing the two delegates. Otherwise,
              // the type of the event handler will be used because we don't need to register the same type of the event handler
              // more than once for each specific event.
              /// </summary>
              private readonly Func<object, object, bool> eventHandlerEquals = (o1, o2) =>
               {
                   var o1Type = o1.GetType();
                   var o2Type = o2.GetType();
                   if (o1Type.IsGenericType &&
                       o1Type.GetGenericTypeDefinition() == typeof(ActionDelegatedEventHandler<>) &&
                       o2Type.IsGenericType &&
                       o2Type.GetGenericTypeDefinition() == typeof(ActionDelegatedEventHandler<>))
                       return o1.Equals(o2);
                   return o1Type == o2Type;
               };
              /// <summary>
              /// 初始化空的事件總件
              /// </summary>
              public static EventBus Instance
              {
                  get
                  {
                      return _eventBus ?? (_eventBus = new EventBus());
                  }
              }
              /// <summary>
              /// 通過XML文件初始化事件總線,訂閱信自在XML里配置
              /// </summary>
              /// <returns></returns>
              public static EventBus InstanceForXml()
              {
                  if (_eventBus == null)
                  {
                      XElement root = XElement.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EventBus.xml"));
                      foreach (var evt in root.Elements("Event"))
                      {
                          List<object> handlers = new List<object>();
      
                          Type publishEventType = Type.GetType(evt.Element("PublishEvent").Value);
                          foreach (var subscritedEvt in evt.Elements("SubscribedEvents"))
                              foreach (var concreteEvt in subscritedEvt.Elements("SubscribedEvent"))
                                  handlers.Add(Type.GetType(concreteEvt.Value));
      
                          eventHandlers[publishEventType] = handlers;
                      }
      
                      _eventBus = new EventBus();
                  }
                  return _eventBus;
              }
      
              #region 事件訂閱&取消訂閱,可以擴展
              /// <summary>
              /// 訂閱事件列表
              /// </summary>
              /// <param name="type"></param>
              /// <param name="subTypeList"></param>
              public void Subscribe<TEvent>(IEventHandler<TEvent> eventHandler)
                  where TEvent : class, IEvent
              {
                  lock (sync)
                  {
                      var eventType = typeof(TEvent);
                      if (eventHandlers.ContainsKey(eventType))
                      {
                          var handlers = eventHandlers[eventType];
                          if (handlers != null)
                          {
                              if (!handlers.Exists(deh => eventHandlerEquals(deh, eventHandler)))
                                  handlers.Add(eventHandler);
                          }
                          else
                          {
                              handlers = new List<object>();
                              handlers.Add(eventHandler);
                          }
                      }
                      else
                          eventHandlers.Add(eventType, new List<object> { eventHandler });
                  }
              }
              /// <summary>
              /// 訂閱事件實體
              /// </summary>
              /// <param name="type"></param>
              /// <param name="subTypeList"></param>
              public void Subscribe<TEvent>(Action<TEvent> eventHandlerFunc)
                  where TEvent : class, IEvent
              {
                  Subscribe<TEvent>(new ActionDelegatedEventHandler<TEvent>(eventHandlerFunc));
              }
              public void Subscribe<TEvent>(IEnumerable<IEventHandler<TEvent>> eventHandlers)
                  where TEvent : class, IEvent
              {
                  foreach (var eventHandler in eventHandlers)
                      Subscribe<TEvent>(eventHandler);
              }
              /// <summary>
              /// 取消訂閱事件
              /// </summary>
              /// <param name="type"></param>
              /// <param name="subType"></param>
              public void Unsubscribe<TEvent>(IEventHandler<TEvent> eventHandler)
                  where TEvent : class, IEvent
              {
                  lock (sync)
                  {
                      var eventType = typeof(TEvent);
                      if (eventHandlers.ContainsKey(eventType))
                      {
                          var handlers = eventHandlers[eventType];
                          if (handlers != null
                              && handlers.Exists(deh => eventHandlerEquals(deh, eventHandler)))
                          {
                              var handlerToRemove = handlers.First(deh => eventHandlerEquals(deh, eventHandler));
                              handlers.Remove(handlerToRemove);
                          }
                      }
                  }
              }
              public void Unsubscribe<TEvent>(IEnumerable<IEventHandler<TEvent>> eventHandlers)
                where TEvent : class, IEvent
              {
                  foreach (var eventHandler in eventHandlers)
                      Unsubscribe<TEvent>(eventHandler);
              }
              public void Unsubscribe<TEvent>(Action<TEvent> eventHandlerFunc)
                  where TEvent : class, IEvent
              {
                  Unsubscribe<TEvent>(new ActionDelegatedEventHandler<TEvent>(eventHandlerFunc));
              }
              #endregion
      
              #region 事件發布
              /// <summary>
              /// 發布事件,支持異步事件
              /// </summary>
              /// <typeparam name="TEvent"></typeparam>
              /// <param name="evnt"></param>
              public void Publish<TEvent>(TEvent evnt)
                 where TEvent : class, IEvent
              {
                  if (evnt == null)
                      throw new ArgumentNullException("evnt");
                  var eventType = evnt.GetType();
                  if (eventHandlers.ContainsKey(eventType)
                      && eventHandlers[eventType] != null
                      && eventHandlers[eventType].Count > 0)
                  {
                      var handlers = eventHandlers[eventType];
                      foreach (var handler in handlers)
                      {
                          var eventHandler = handler as IEventHandler<TEvent>;
                          if (eventHandler.GetType().IsDefined(typeof(HandlesAsynchronouslyAttribute), false))
                          {
                              Task.Factory.StartNew((o) => eventHandler.Handle((TEvent)o), evnt);
                          }
                          else
                          {
                              eventHandler.Handle(evnt);
                          }
                      }
                  }
              }
      
              public void Publish<TEvent>(TEvent evnt, Action<TEvent, bool, Exception> callback, TimeSpan? timeout = null)
                 where TEvent : class, IEvent
              {
                  if (evnt == null)
                      throw new ArgumentNullException("evnt");
                  var eventType = evnt.GetType();
                  if (eventHandlers.ContainsKey(eventType) &&
                      eventHandlers[eventType] != null &&
                      eventHandlers[eventType].Count > 0)
                  {
                      var handlers = eventHandlers[eventType];
                      List<Task> tasks = new List<Task>();
                      try
                      {
                          foreach (var handler in handlers)
                          {
                              var eventHandler = handler as IEventHandler<TEvent>;
                              if (eventHandler.GetType().IsDefined(typeof(HandlesAsynchronouslyAttribute), false))
                              {
                                  tasks.Add(Task.Factory.StartNew((o) => eventHandler.Handle((TEvent)o), evnt));
                              }
                              else
                              {
                                  eventHandler.Handle(evnt);
                              }
                          }
                          if (tasks.Count > 0)
                          {
                              if (timeout == null)
                                  Task.WaitAll(tasks.ToArray());
                              else
                                  Task.WaitAll(tasks.ToArray(), timeout.Value);
                          }
                          callback(evnt, true, null);
                      }
                      catch (Exception ex)
                      {
                          callback(evnt, false, ex);
                      }
                  }
                  else
                      callback(evnt, false, null);
              }
      
              #endregion
      
          }

      一個具體的領域對象,它繼承IEvent

          /// <summary>
          /// 添加訂單的事件
          /// </summary>
          public class OrderGeneratorEvent : IEvent
          {
              public int OrderID { get; set; }
          }

      一個為OrderGeneratorEvent工作的領域事件,它用來為客戶發郵件

         /// <summary>
          /// 發郵件功能
          /// </summary>
          public class OrderAddedEventHandler_SendEmail : IEventHandler<OrderGeneratorEvent>
          {
              public void Handle(OrderGeneratorEvent evt)
              {
                  Console.WriteLine("Order_Number:{0},Send a Email.", evt.OrderID);
              }
          }

      下面看一個主程序:

         static void Main(string[] args)
          {
                EventBus.Instance.Subscribe(new OrderAddedEventHandler_SendEmail());
                  var entity = new OrderGeneratorEvent { OrderID = 1 };
                  Console.WriteLine("生成一個訂單,單號為{0}", entity.OrderID);
                  EventBus.Instance.Publish(entity);
                  Console.ReadKey(); }

      下面是運行結果:

      嗨,終于理解這東西了,呵呵,在此感謝一下晴陽兄,它對DDD的貢獻非常大...

      回到目錄

      posted @ 2013-12-16 14:21  張占嶺  閱讀(16151)  評論(10)    收藏  舉報
      主站蜘蛛池模板: 精品亚洲国产成人| 人妻中文字幕精品系列| 国产av一区二区三区久久| 天堂中文8资源在线8| 国产精品99一区二区三区| 四虎永久精品在线视频| 亚洲人成电影在线天堂色| 亚洲尤码不卡av麻豆| 中文字幕人妻日韩精品| 最新国产AV最新国产在钱| 人妻少妇无码精品专区| 人妻少妇精品无码专区二区| 国产女人喷潮视频免费| 久久这里只精品国产免费9| 精品国精品自拍自在线| 永宁县| 国产午夜福利一区二区三区| 亚洲一二三区精品美妇| 无码人妻丰满熟妇区毛片| 色欲久久综合亚洲精品蜜桃| 午夜福利在线观看6080| 999精品全免费观看视频| 影音先锋女人AA鲁色资源| 亚洲国产精品久久无人区| 亚洲国产高清第一第二区| 亚洲国产日韩欧美一区二区三区 | 乱人伦人妻中文字幕不卡| 国产亚洲精品在av| 成人网站免费观看| 日韩精品一区二区三区不卡| 公天天吃我奶躁我的在线观看| 人人澡人摸人人添| 福利网午夜视频一区二区| 国产国语一级毛片| 亚洲欧美日韩在线不卡| 萍乡市| 久久99热只有频精品8| 又长又粗又爽又高潮的视频| 1区2区3区4区产品不卡码网站 | 亚洲va成无码人在线观看天堂| 蜜臀av一区二区三区日韩|