Lind.DDD.Events領域事件介紹

来源:http://www.cnblogs.com/lori/archive/2016/01/29/5168935.html
-Advertisement-
Play Games

回到目錄 閑話多說 領域事件大叔感覺是最不好講的一篇文章,所以拖欠了很久,但最終還是在2015年年前(陰曆)把這個知識點講一下,事件這個東西早在C#1.0時代就有了,那時學起來也是一個費勁,什麼是委托,哪個是事件,搞的大家是糊裡糊塗,進入C#2.0時代後,大叔也買了一本書,對於delegate和ev


回到目錄

閑話多說

領域事件大叔感覺是最不好講的一篇文章,所以拖欠了很久,但最終還是在2015年年前(陰曆)把這個知識點講一下,事件這個東西早在C#1.0時代就有了,那時學起來也是一個費勁,什麼是委托,哪個是事件,搞的大家是糊裡糊塗,進入C#2.0時代後,大叔也買了一本書,對於delegate和event這兩個知識點看了至少有20幾遍,感覺稍微有點明白了,明白了其中的真諦和用意。

委托:方法的規範,方法的模板,可以代表一類方法的集合

事件:委托的實例,事件在使用之前需要為它賦值,當然賦的就是一個方法;事件可以註冊和取消,當你註冊一個事件之後,在事件被觸發後,被註冊的方法將會被執行,這一般被稱為“方法的回調”,在設計模式里,又被稱為“pub/sub模式”,即發佈/訂閱模式;在C#語言發展過程中,設計得為程式開發者考慮的很多,有些寫法得到了精簡,如Action和Func委托的出現之後,我們基本上告別了delegate,這對程式開發人員無疑是一件好事。

大叔框架中的事件

在大叔框架里,事件是常客,比如在早期的倉儲代碼里,你可以傳遞一個Action<string>的委托,來進行日誌的記錄,這種方法在IoC出現後,被大叔屏蔽了,原因不在這裡說了,還有就是在N層架構里,WEB層與BLL層進行通訊時,WEB層通過HttpClient請求第三方的API獲取數據,而BLL層的方法需要用到這個第三方API的返回值,而在BLL層直接訪問HTTP顯然是不合適的,所以,在WEB層到BLL層的方法參數設計時,需要有一個委托來接改從WEB層回調的方法返回值,這種代碼一般稱為“方法回調”。

web層向BLL層傳入一個委托

  var entity = rechargeService.RechargeAuto(
                        task,
                        beforeTime,
                        out result,
                        (studentid, money) =>
                        {
              //代碼
              });

 

BLL層接改這個委托的返回值,代碼在調用bll層這個方法時,首先會回調web層的http的方法

public Task_xuexiba_Recharge RechargeAuto(
         Task_Info task,
         DateTime beforeTime,
         out bool result,
         Func<int, decimal, RechargeXuexibaDTO> api)
        {
      //代碼
      }
  var apiEntity = api(task.Task_ParametersForXuexibaRecharge.StudentID, task.Task_ParametersForXuexibaRecharge.Money);

Lind.DDD框架里的領域事件

事件源尾碼:Event

事件處理方法尾碼:EventHandler

領域事件一般出現個領域實體里,在實體被建立時,會訂閱和自己有關的事件,每個事件都有一個或者多個事件處理方法,事件處理方法可以進行資料庫操作,或者網路和文件的操作,如發通知,寫文件等,所以有時候我們的事件需要設計成非同步的事件。

程式中的事件事件

  #region 領域模型
    public class Order
    {
        public Order()
        {
            Lind.DDD.Events.EventBus.Instance.Subscribe(new OrderInsertEventHandler());
            Lind.DDD.Events.EventBus.Instance.Subscribe<OrderPaid>(new OrderUpdateEventHandler());
        }

        public System.Guid Id { get; set; }
        public System.Guid UserId { get; set; }
        public string UserName { get; set; }
        public decimal TotalFee { get; set; }

        /// <summary>
        /// 用戶提交並確認訂單
        /// </summary>
        public void ComfirmOrder()
        {
            //事件發佈
            Lind.DDD.Events.EventBus.Instance.Publish(new OrderConfirm
            {
                TotalFee = TotalFee,
                UserName = UserName,
                UserId = UserId,
            });
        }

    }

    #endregion

下麵是領域事件源

   /// <summary>
    /// 訂單被確認的事件源
    /// </summary>
    public class OrderConfirm : Lind.DDD.Events.IEvent
    {
        public override string ToString()
        {
            return "訂單已經確認";
        }
        /// <summary>
        /// 訂單總金額
        /// </summary>
        public decimal TotalFee { get; set; }
        /// <summary>
        /// 購買者ID
        /// </summary>
        public Guid UserId { get; set; }
        /// <summary>
        /// 購買者
        /// </summary>
        public string UserName { get; set; }

        #region IEvent 成員

        public Guid AggregateRoot
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }

下麵是領域事件的處理程式

   /// <summary>
    /// 訂單被插入時的處理程式
    /// </summary>
    public class OrderInsertEventHandler :
          Lind.DDD.Events.IEventHandler<Events.OrderConfirm>
    {
        #region IEventHandler<OrderSigned> 成員

        public void Handle(Events.OrderConfirm evt)
        {
            //處理訂單確認的邏輯
            var orderRepository = new Lind.DDD.Repositories.EF.EFRepository<Orders>();
            orderRepository.SetDataContext(new testEntities());
            orderRepository.Insert(new Orders
            {
                Id = Guid.NewGuid(),
                OrderStatus = 1,
                TotalFee = evt.TotalFee,
                UserId = evt.UserId,
                UserName = evt.UserName,
            });
        }

        #endregion
    }

如果希望將自己的事件處理程式設計成異常的,即不阻塞當前線程的,可以讓它添加HandlesAsynchronouslyAttribute這個特性,如下麵這個發送Email的處理程式就是一個非同步的。

  /// <summary>
    /// 發郵件功能[某個事件的行為]
    /// </summary>
    [HandlesAsynchronouslyAttribute]
    public class SendEmailEventHandler :
        IEventHandler<OrderEvent>,
        IEventHandler<UserEvent>
    {

        #region IEventHandler<OrderEvent> 成員

        public void Handle(OrderEvent evt)
        {
            Console.WriteLine("生成和確認訂單{0}時發Email", evt.OrderId);
        }

        #endregion

        #region IEventHandler<UserEvent> 成員

        public void Handle(UserEvent evt)
        {
            Console.WriteLine("建立用戶後發Email,用戶ID{0}", evt.UserId);
        }

        #endregion
    }

 

感謝各位的閱讀!

回到目錄


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 類和結構體: 定義語法: class SomeClass{ //定義類的成員 var name:String = "" var age:Int = 18 var job:String?//可選可以為空 } struct SomeStruct{ //定義結構體的成員 let sex:String =
  • Python中的變數不需要聲明。每個變數在使用前都必須賦值,變數賦值以後該變數才會被創建。 在Python中變數就是變數,是記憶體地址指針,它沒有類型,我們所說的"類型"是變數所指的記憶體中對象的類型。類似於其他java、C中的引用類型。 Python3中有六個標準的數據類型: 字元串(String)數
  • #應用環境:python2.7#!/usr/bin/env python # coding=utf-8 from __future__ import print_function import os try: from urllib import urlencode, quote_plus exce
  • "Gist Link" 看完我想撞牆,為什麼早沒想到。。。
  • Github 地址 項目背景 最近做個項目,需要進行試駕分析,所謂“試駕”,是指顧客在 4S 店指定人員的陪同下,沿著指定的路線駕駛車輛,從而瞭解這款汽車的行駛性能和操控性能。通常,無論是車廠(製造商),還是4S店(經銷商),對車輛的試駕都比較感興趣。從車廠的角度,不僅僅可以知道某輛車是否受歡迎,還...
  • 1.記憶體分區: 高(記憶體地址大) 棧底 棧區 堆區 靜態區 常量區 低(記憶體地址小) 代碼區 2.棧:數據結構 (1)特點:先進後出 (2)操作:入棧(push)出棧(pop) (3)棧從高->低分配空間 char a = 0; char b = 0; char c = 0; printf(“a:%
  • 在文章《Python開發、調試、爬蟲類工具大全》裡面向大家總結了各種實用工具和爬蟲技術,今天小編收集了5篇帶有實例乾貨的資料,趕緊來看看吧!另外,喜歡寫博客的博主可以申請加工程師博主交流群:391519124,分享你的博文,和大牛們一起交流技術~ 一、OSINT + Python = 自定義黑客Py
  • 說到外觀模式,很容易想到的是設計一件漂亮的衣服然後穿上自己的身上,讓自己看起來更加的漂亮,但是這個可能並不是這樣子的,從更深層次的來說,外觀更應該是所見即所得的,對於觀眾來說,看起來可能就是很簡單,但是裡面所有的東西的複雜程度,我們並不知道。 在程式開發的過程中,我們時常的會用到一些類與類之間的關聯
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...