1 回答

TA貢獻1846條經(jīng)驗 獲得超7個贊
這將取決于具體情況。我將嘗試解釋幾個不同的問題及其解決方案。
您有一個系統(tǒng),其中審計信息自然是域的一部分。
讓我們舉一個簡單的例子:
在Bank和Person之間簽訂合同的銀行系統(tǒng)。銀行由BankEmployee代表。簽署或修改合同時,您需要在合同中包含有關誰做的信息。
public class Contract {
public void AddAdditionalClause(BankEmployee employee, Clause clause) {
AddEvent(new AdditionalClauseAdded(employee, clause));
}
}
您有一個系統(tǒng),其中審計信息不是域的自然組成部分。
這里有幾件事需要解決。例如,用戶可以只向您的系統(tǒng)發(fā)出命令嗎?有時另一個系統(tǒng)可以調(diào)用命令。
解決方案:記錄所有的傳入命令及其處理后的狀態(tài):成功、失敗、拒絕等。
包括命令發(fā)布者的信息。
記錄命令發(fā)生的時間。您可以在命令中包含有關發(fā)行者的信息,也可以不包含。
public interface ICommand {
public Datetime Timestamp { get; private set; }
}
public class CommandIssuer {
public CommandIssuerType Type { get; pivate set; }
public CommandIssuerInfo Issuer {get; private set; }
}
public class CommandContext {
public ICommand cmd { get; private set; }
public CommandIssuer CommandIssuer { get; private set; }
}
public class CommandDispatcher {
public void Dispatch(ICommand cmd, CommandIssuer issuer){
LogCommandStarted(issuer, cmd);
try {
DispatchCommand(cmd);
LogCommandSuccessful(issuer, cmd);
}
catch(Exception ex){
LogCommandFailed(issuer, cmd, ex);
}
}
// or
public void Dispatch(CommandContext ctx) {
// rest is the same
}
}
優(yōu)點:這將從有人發(fā)出命令的知識中刪除您的域
缺點:如果您需要有關事件更改和匹配命令的更多詳細信息,您將需要匹配時間戳和其他信息。根據(jù)系統(tǒng)的復雜性,這可能會變得很難看
解決方案:記錄entity/aggregate中的所有incomming命令和相應的事件。查看本文以獲取詳細示例。CommandIssuer您可以在事件中包含。
public class SomethingAggregate {
public void Handle(CommandCtx ctx) {
RecordCommandIssued(ctx);
Process(ctc.cmd);
}
}
你確實將一些來自外部的信息包含到你的聚合中,但至少它是抽象的,所以聚合只是記錄它??雌饋磉€不錯,是嗎?
解決方案:使用將包含有關您正在使用的操作的所有信息的傳奇。在分布式系統(tǒng)中,大多數(shù)時候你需要這樣做,所以它會是一個很好的解決方案。在另一個系統(tǒng)中,它會增加您可能不想擁有的復雜性和開銷 :)
public void DoSomethingSagaCoordinator {
public void Handle(CommandContext cmdCtx) {
var saga = new DoSomethingSaga(cmdCtx);
sagaRepository.Save(saga);
saga.Process();
sagaRepository.Update(saga);
}
}
我已經(jīng)使用了此處描述的所有方法以及您的Option 2的變體。在我處理請求時的版本中,他們Repositoires可以訪問context包含用戶信息的對象,因此當他們保存事件時,此信息包含在EventRecord同時具有事件數(shù)據(jù)和用戶信息的對象中。它是自動化的,因此其余代碼與它分離。我確實使用 DI 將上下文注入存儲庫。在這種情況下,我只是將事件記錄到事件日志中。我的聚合不是事件來源的。
我使用這些準則來選擇一種方法:
如果它是一個分布式系統(tǒng) -> 去 Saga
如果不是:
我是否需要將詳細信息與命令相關聯(lián)?
是:傳遞
Commands
和/或CommandIssuer
信息到聚合
如果沒有那么:
數(shù)據(jù)庫是否具有良好的事務支持?
是:保存
Commands
在CommandIssuer
聚合之外。否:保存
Commands
并CommandIssuer
匯總。
- 1 回答
- 0 關注
- 157 瀏覽
添加回答
舉報