gpt4 book ai didi

cqrs - 在 Event Sourcing 中创建大型事件是否可以?

转载 作者:行者123 更新时间:2023-12-04 15:35:46 25 4
gpt4 key购买 nike

我们正在使用事件源并从事件流构建聚合。
我有 2 个聚合 - A1 和 A2。 A1 用作模板以创建 A2。
A1 的大小可以相当大。
事件溯源的基本思想是确保应用程序状态的每个更改都在事件对象中捕获。
所以为了保存A2,我们必须在第一个事件中存储很多信息。

这种情况是常见的还是从模板创建不是一个好主意?
有没有更好的方法来解决它?

最佳答案

如果您发布更具体的聚合和事件示例,将会更有帮助。一般来说,如果在您的情况下有意义,您可以创建更细粒度的事件。然后,命令和事件之间不再是 1-1 关系,而是 1-N 关系,这完全符合 CQRS 理论。

所以给你一个例子:

CreateInvoice : Command
- InvoiceId
- Customer (10 fields)
- Address (5 more fields)
- InvoceLine[] (where each InvoiceLine also have 10 fields or so)
- Rest of 100 or so fields

InvoiceCreated : Event
- InvoiceId
- Customer (10 fields)
- Address (5 more fields)
- InvoceLine[] (where each InvoiceLine also have 10 fields or so)
- Total
- Rest of 100 or so fields

在命令处理程序中:
void Handle(CreateInvoce cmd)
{
var invoice = new Invoice(cmd.InvoiceId, cmd.Customer, cmd.Address, cmd.Lines ....)
uow.Register(invoice);
}

其中只会引发一个 InvoceCreated 事件。

相反,您可以拥有更细粒度的事件:
InvoiceCreated : Event
- InvoiceId
- Customer
- Address

InvoiceLineAdded
- InvoiceId
- Item
- Vat
- Subtotal
- Etc

然后在命令处理程序中:
void Handle(CreateInvoce cmd)
{
var invoice = new Invoice(cmd.InvoiceId, cmd.Customer, cmd.Address);

foreach (var line in cmd.Lines)
{
invoice.AddLine(line.Item, line.Quantity, line.Price, ...);
}

uow.Register(invoice);
}

这里 ctor 将引发 InvoiceCreated 事件,而 AddLine 方法将引发 InvoiceLineAdded 事件。
然后,您可以拥有诸如 InvoiceLineChanged/InvoiceLineRemoved 之类的事件,您可以将其与更新一起使用。

这将允许您拥有更细粒度的事件,同时仍然允许发出更粗粒度的命令。

大命令是可以的,当它们代表来自用户/系统 PoV 的原子操作时。

附言关于使用聚合作为模板,我不会为此烦恼,而是将创建数据结构作为收集中间状态的累加器。然后它可以被简单地序列化/反序列化。如果填充模板背后没有行为 - 那么您根本不需要聚合。它只是一组数据,稍后将用于创建聚合和运行业务规则。您可能正在使用这个"template"对象来存储多个请求之间的用户输入状态,例如 session 状态,对吧;)?

希望有帮助。

关于cqrs - 在 Event Sourcing 中创建大型事件是否可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10954877/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com