第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

DDD:有沒有一種優(yōu)雅的方法可以在更新聚合根時傳遞審計信息?

DDD:有沒有一種優(yōu)雅的方法可以在更新聚合根時傳遞審計信息?

C#
一只名叫tom的貓 2023-04-16 10:00:18
假設我有一個如下所示的 CQRS 命令:public sealed class DoSomethingCommand : IRequest{    public Guid Id { get; set; }    public Guid UserId { get; set; }    public string A { get; set; }    public string B { get; set; }}這是在以下命令處理程序中處理的:public sealed class DoSomethingCommandHandler : IRequestHandler<DoSomethingCommand, Unit>{    private readonly IAggregateRepository _aggregateRepository;    public DoSomethingCommand(IAggregateRepository aggregateRepository)    {       _aggregateRepository = aggregateRepository;    }    public async Task<Unit> Handle(DoSomethingCommand request, CancellationToken cancellationToken)    {        // Find aggregate from id in request        var id = new AggregateId(request.Id);        var aggregate = await _aggregateRepository.GetById(id);        if (aggregate == null)        {            throw new NotFoundException();        }        // Translate request properties into a value object relevant to the aggregate        var something = new AggregateValueObject(request.A, request.B);        // Get the aggregate to do whatever the command is meant to do and save the changes        aggregate.DoSomething(something);        await _aggregateRepository.Save(aggregate);        return Unit.Value;    }}我需要保存審計信息,例如“CreatedByUserID”和“ModifiedByUserID”。這是一個純粹的技術問題,因為我的業(yè)務邏輯都不依賴于這些字段。我在這里找到了一個相關的問題,其中有人建議引發(fā)一個事件來處理這個問題。這將是一種很好的方法,因為我還使用類似于此處描述的方法,基于從聚合引發(fā)的域事件來持久化更改。(TL;DR:將事件添加到聚合中的每個操作的集合中,將聚合傳遞給Save存儲庫中的單個方法,在該存儲庫方法中使用模式匹配來處理存儲在聚合中的每個事件類型以持久保存更改)
查看完整描述

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ù)庫是否具有良好的事務支持?

  • 是:保存CommandsCommandIssuer聚合之外。

  • 否:保存CommandsCommandIssuer匯總。


查看完整回答
反對 回復 2023-04-16
  • 1 回答
  • 0 關注
  • 157 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號