2016-11-18 27 views
4

我可以想到兩個地方將域邏輯放在事件源系統中,或者有一個缺點。事件採購:何處放置業務邏輯

  • 在創建事件後在本地調用的聚合的事件處理程序。 (這是我在大多數examples中看到的,雖然他們大多數都有非常簡單的邏輯)
    問題:存儲在事件存儲器中併發布給訂閱者的事件不包含此處理的數據,因此在投影時同一邏輯必須應用於該事件。
  • 創建活動之前。現在處理的數據可以存儲在事件中,並且投影不必知道任何有關業務邏輯的信息。 (我在示例中沒有看到這種方法)
    問題:在這種情況下,儘管事件只包含可能導致信息丟失的已處理數據。
    更糟糕的是:由於事件數據已經計算出來,我也放棄了通過重播事件來糾正錯誤的業務邏輯的可能性。

示例:從某些數據計算度量標準。
要麼我必須計算兩次公式(一次在域模型中,一次在投影中)
或者我必須在發送事件並將其包括在內之前計算它。

回答

4

控制的流程通常是這樣的:

  • 命令被髮送到在所述命令的命令處理程序和屬性是預先驗證,如身份指向現有實體和所有強制信息存在,並且在正確的格式
  • 命令處理程序檢索來自庫的集合(通過讀取事件流,但是這並不重要),並調用根據需要由該命令
  • 骨料做什麼總法(S)方法必須確保它們的參數和aggre門狀態相互允許執行操作。

  • 總計方法,然後創建一個事件,並呼籲該WhenApply方法來處理事件

  • 事件處理變異聚集狀態,沒有邏輯存在!然後

  • 控制流返回到命令處理程序,並堅持所有的新事件在店裏

進一步的動作都與預測。

在應用事件之前,將不變保護又稱業務邏輯放入聚合事件的原因是,事件生成時不會退回。這件事已經發生了。你不能否認應用一個事件。考慮從事件流中恢復聚合時重放事件(從存儲庫中讀取),如果有一天您決定在那裏使用if-throw組合,該如何工作?

因此,簡而言之:

    被髮送的命令之前被施加
  • 初始邏輯
  • 一些附加的邏輯是在命令處理程序在聚合方法
  • 骨料保護(很可能是也命令處理程序)
  • 在事件處理程序沒有邏輯,只有狀態突變

沒有人EV呃說事件採購會幫助你解決計算中的問題。爲了建立一個額外的安全網絡,你可能想要保存命令,但是你將不得不發佈補償事件或截斷流,這實際上並不是你想要做的。

+0

修復計算問題被一些人明確描述爲一項好處。請參閱此處:「修復錯誤您可能會發現導致系統計算錯誤值的編碼錯誤,而不是修復編碼錯誤並對存儲的數據項執行有風險的手動調整,您可以修復編碼錯誤並重放事件流,以便系統根據新版本的代碼正確計算值。「 (從https://msdn.microsoft.com/en-us/library/jj591559.aspx#sec2) 但除此之外,謝謝澄清。 – hybridtupel

+1

如果計算髮生在讀取模型的投影中 - 這確實有意義。事件中的計算適用於變更聚合狀態不變。 –

0

我想你在你的聚合根中有一些狀態。這應該包含關於您的業務的邏輯。所以它應該有足夠的數據來根據命令創建事件。
此事件的消費者(查詢模型)進行計算。所以如果意圖是計算平均值,它必須設法以給定的方式存儲自己。
我做了類似的事情。一旦它是業務邏輯的一部分,它就在Aggregate中,一旦它在Query模型中,因爲它不是業務邏輯的一部分,而是更多的度量計算。
不要害怕將數據存儲在多個地方。一致性的責任應該委託給事件分發,而不是你的業務邏輯。

+0

你有一些圖形你怎麼做到的? – hybridtupel

+0

我不太清楚最後一部分,所以你說你拆分邏輯,一部分在聚合中,另一部分在查詢模型中? – hybridtupel

+0

這裏是很好的文章,其中描述了CQRS/ES。 https://msdn.microsoft.com/en-us/library/jj591559.aspx – hellxcz