2014-02-28 32 views
1

this question稍有關係:我是否應該將存儲庫傳遞給需要在方法操作發生並保持後才觸發事件的域對象方法?我應該將資源庫傳遞給域方法引發事件的方法

在這種情況下,系統需要在域對象狀態更改後發送電子郵件。雖然不太可能,但可能發生的情況是,在不發送電子郵件的情況下,狀態更改不會持續。

我可以用一個域名服務做的工作,但狀態變化的所有邏輯所屬包含在域對象,所以我的服務最終會看起來像

StatusService(Irepo repo) { 

     void ChangeStatus(domainObject myObject, status newStatus) { 
       try { 
       myObject.ChangeStatus(newStatus); 
       repo.Save(myObject); 
       raiseEvent(new StausChangeEmailEvent(myObject)) 
       } catch { .. dont send email } 
     } 

哪個ID寧願不做由於幾個原因(其中之一是現在有2種方式更改狀態,其中只有一種發送電子郵件)

編號喜歡把它包裝在域方法本身,但這也不覺得正確,因爲我'使域對象負責自己的持久性。 (雖然我覺得我更喜歡在域名服務方式)

class DomainObject() : IAggRoot { 

... 
public ChangeStatus(irepo repo, status newStatus) { 
    ..logic logic 
    this.Status = newStatus; 
    repo.Save(this); 
    raiseEvent(new StausChangeEmailEvent(myObject)) 
} 

} 

有一些關於業務邏輯的併發症,但我真的很感興趣如何觸發事件域對象被持久化之後。

編輯:如果電子郵件發送失敗並不重要,如果狀態不「發送」,組織中的高級人員可能會收到其郵箱中的無效指令,因此不發送電子郵件非常重要。

+0

你關心發送郵件是否失敗嗎? – JefClaes

+0

好問題 - 如果電子郵件部分失敗,沒有它那麼重要。 – Joe

回答

1

具有一致的事務行爲會更好。你可以在同一個事務(隊列或數據庫)中提交事件,並從那裏派發。無論如何,如果這不是你正在尋找的東西,你也可以讓你的聚合記錄事件,而不是直接提高它。這使您可以首先提交數據庫事務,然後分派事件。

public interface IRecordingAggRoot { 
    IEnumerable<IEvent> RecordEvents(); 
} 

_repository.Save(aggregate); 
_tx.Commit(); 
_dispatcher.Dispatch(aggregate.RecordedEvents()); 
+0

但是這個邏輯(commit; dispatch;)在哪裏?我考慮的越多,我認爲'服務'越多 - 但其中:應用程序或域服務?電子郵件是企業與地位變更操作相關的強大要求,但發送電子郵件失敗的事實在某種程度上可以接受。另外,如果我將其包裝在調用domainModelObject上的changeStatus函數的應用程序服務中,我可能會遇到以下情況,開發人員直接調用chageStatus而不使用服務來確保正確的事件順序。 (救援內部?) – Joe

+0

好吧,我現在明白了 - 花了一點錢讓這筆錢掉下來。域對象構建其記錄事件的集合,應用層程序負責在無錯誤commit()後處理任何事件。我發現這篇文章也很有幫助http://www.jayway.com/2013/06/20/dont-publish-domain-events-return-them/ – Joe

+0

見http://www.jefclaes.be/2014/03 /alternatives-to-udis-domain-events.html。 – JefClaes

相關問題