2011-06-09 65 views
15

短信在這個時刻,我們正在建立一個基於CQRS的原則和領域驅動設計的新架構。現在我們正在討論如何處理外部溝通問題。爲了更具體地提出問題,我使用了客戶創建訂單時發送短信通知的示例。發送e-mail或使用CQRS和領域驅動設計

客戶端創建由關聯的命令處理程序來處理一個NewOrderCommand。處理程序在域模型中創建一個新的Order對象,該對象生成一個NewcustomerCreatedEvent。該對象保存在事件存儲中,並將事件發佈給所有偵聽器。

到目前爲止好,但現在的問題。我們應該在哪裏發送短信通知?

我們的第一直覺告訴我們,我們應該用一個事件偵聽器偵聽NewCustomerCreatedEvent併發出消息發送出去。這種方法的問題在於發送SMS也是我們業務邏輯的一部分。我們銷售託管服務,因此我們的客戶應該能夠看到代表他們發送的所有SMS消息。由於郵件的發送發生在域外,所以我們無法做到這一點。

所以我們創建了一個SMS域,現在當事件監聽器接收NewCustomerCreatedEvent事件處理程序創建一個新的命令SendSmsMessageCommand,將在我們的站點上創建新SMSMessage對象,發出短信通知,並創建一個SmsSent事件,我們用來創建視圖。

起初,我們在領域模型是發送SMS消息,但我們意識到,這可能給了一些問題。假設在發送SMS之後發生了一些事情(引發異常)並且事務被回滾。我們的域名完全支持這個數據,因此我們可以確定,但是SMS消息已經發送,所以當命令重新發送時,SMS通知將被再次發送。

我們想在SmSSent事件發出短信,但是這將是一個有點陌生,因爲該事件表示已經發出的信息,但並非如此。上述

的例子給我們帶來了問題,如何處理在CQRS外部通信和領域驅動設計理念?我們不僅在談論發送短信通知,還談論發送發票給外部計費系統和所有其他類型的通信到外部世界。我們是否應該在域中執行此操作,因爲它的業務邏輯或者我們應該始終根據事件處理程序中的事件來執行此操作?如果我們這樣做,是否可以接受使用事件來說明消息在實際沒有完成時發送?

希望你們已經處理了這種情況,可以給我們一些關於這個問題的建議。

+1

恥辱,這個問題沒有吸引更多的興趣。你有沒有在這個問題上取得進一步的進展/想法?你有沒有重播活動重新建立閱讀商店?在這種情況下,你如何確保短信不再被髮送? – Kimble 2012-06-13 13:13:33

+1

相關:http://stackoverflow.com/questions/11015989/cqrs-when-to-send-confirmation-message?rq=1 // @Kimble – 2012-08-09 00:50:14

回答

2

我會認爲SMS消息的域對象是沒有必要的。您只需要將發送給客戶的SMS報告,對嗎? SMS消息不在任何域邏輯中使用,對嗎?

所以我會讓處理程序發送一條短信,然後發佈另一個事件,說SMS已發送並且有一個事件處理程序偵聽SMS發送的消息並在讀取模型中實現該信息,以便客戶可以查看它們。

+0

感謝您的回答。 SMS實際上只是一個例子。就像我在一般的外部交流中所說的那樣。當我將SMS更改爲HTTP POST到我們的計費系統時,您的建議是相同的,以便在事件處理程序中實際發送該消息,並讓該事件處理程序創建新事件。 只是爲了解釋我們爲什麼創建和SMS域是因爲我們是我們自己的SMS經紀人。當我們發送像運營商發送的短信時,涉及到很多業務邏輯。我們還應該能夠處理SMS消息的投遞報告。 – llMll 2011-06-09 20:33:15

0

您可以使用佐賀或微軟所稱的進程管理器。它基本上監聽事件,這會改變傳奇的狀態,並根據傳奇中實現的狀態邏輯發出命令。

你的情況,這將是兩個國家的傳奇,那等待兩個CustomerCreatedEvent和OrderCreatedEvent,並且,無論是發出命令,發送一個短信,如果你有通信專業界上下文,或致電基礎設施服務,通過一個接口發送短信。

在這裏你可以找到微軟的傳奇/進程管理器模式的文章:

https://msdn.microsoft.com/en-us/library/jj591569.aspx

而且兩篇文章包含實現:

http://danielwhittaker.me/2015/03/31/how-to-send-emails-the-right-way-in-a-cqrs-system/

http://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/