2012-07-18 77 views
2

我試圖圍繞CQRS我的頭。我從提供的代碼示例here中繪製。請溫柔我對這種模式很陌生。CQRS - 當命令無法解析到域

我正在查看登錄方案。我喜歡這個場景,因爲它在我讀過的任何例子中都沒有被真正展示過。在這種情況下,我不知道用戶的聚合ID是什麼,或者即使有一個,因爲我開始的是用戶名和密碼。

在fohjin例子事件總是從域發射(如果需要)和命令處理程序調用上的域一些方法。但是,如果用戶登錄無效,我沒有任何域可以調用任何東西。同樣,大多數(如果不是全部)在fohjin項目中定義的基本Command/Event類都傳遞一個聚集ID。

在事件的情況下LogonFailure我可能要更新LogonAudit報告。

所以我的問題是:如何處理命令不解析爲一個特定的彙總?這將如何流動?

public void Execute(UserLogonCommand command) 
    { 
     var user = null;//user looked up by username somehow, should i query the report database to resolve the username to an id? 

     if (user == null || user.Password != command.Password) 
      ;//What to do here? I want to raise an event somehow that doesn't target a specific user 
     else 
      user.LogonSuccessful(); 
    } 
+1

我在CQRS + ES上寫了一個MembershipProvider,如果你[想看一看](https://github.com/Iridio/CQRS-ES_MembershipProvider) – Iridio 2012-07-20 11:49:09

+0

謝謝,這對我有幫助。它似乎忽略登錄嘗試的記錄,但不匹配現有的用戶名。這是我的問題的核心 – Sam 2012-07-24 04:38:28

+0

失敗的嘗試存儲在Faliedpassword嘗試和FailedPasswordQuestionAndAnswerAtwerpt和相對日期時間 – Iridio 2012-07-24 06:37:12

回答

3

您應該考慮到,大多數情況下CQRS和DDD僅適用於系統的某些部分。使用CQRS概念對整個系統進行建模是非常罕見的 - 它最適合具有複雜業務領域的部分,並且我不會在特別複雜的業務場景中調用登錄用戶。事實上,在大多數情況下,它根本不是與商業相關的。當用戶已被識別時,實際的業務域開始。

另一件事要記住的是,由於最終一致性是非常有益的,檢查的多,我們可以僅使用查詢側,沒有事件產生的任何命令/事件。然而

假設,即約成功/失敗的用戶登錄功能的信息是有意義的我想你的情況有以下步驟

  1. 用戶提供名和密碼
  2. 名稱/密碼對一些模型驗證這種查詢數據庫的
  3. 當提供的憑證(用戶ID)執行有效RegisterValidUserCommand導致合適的事件
  4. 如果提供的憑據無效 RegisterInvalidCredentialsCo命令(providedUserName)被執行導致適當的事件

問題是檢查用戶憑證不一定是業務域的一部分。

不過,還有另一個相關的概念,其中不是每個命令或事件必須是業務 - 相關的,因此可以處理不需要聚集到加載事件。

例如你想改變的數據就是信息只,絕不會影響您的系統的企業經營理念,如對人的性別信息(再次,假設它沒有業務含義)。

在這種情況下,當您處理SetPersonSexCommand時,實際上不需要加載聚合,因爲該信息甚至不必位於實體上,而是創建PersonSexSetEvent,註冊它併發布,以便查詢端可以將其投影到屏幕/ raport。

+0

同意。雖然用戶訪問域可能是你想要建模的東西。 – 2012-07-19 15:01:31

+0

因此,您的建議是避免查詢除命令內的寫入存儲之外的其他任何內容?我想我需要一個單獨的抽象/事件存儲來處理沒有針對特定聚合的事件(因爲我仍然希望通過事件採購來重現失敗)。我認爲這個登錄場景最符合你的第二個例子,它對實體沒有任何意義。我只是對在哪裏進行身份驗證檢查感到困惑。感謝您的回覆。 – Sam 2012-07-20 00:46:16

+2

使用cqrs對此進行建模的另一個問題是在命令和/或事件中記錄明文密碼 – Kimble 2012-07-31 22:27:48