2016-11-18 76 views
4

我可以想到两个地方将域逻辑放在事件源系统中,或者有一个缺点。事件采购:何处放置业务逻辑

  • 在创建事件后在本地调用的聚合的事件处理程序。 (这是我在大多数examples中看到的,虽然他们大多数都有非常简单的逻辑)
    问题:存储在事件存储器中并发布给订阅者的事件不包含此处理的数据,因此在投影时同一逻辑必须应用于该事件。
  • 创建活动之前。现在处理的数据可以存储在事件中,并且投影不必知道任何有关业务逻辑的信息。 (我在示例中没有看到这种方法)
    问题:在这种情况下,尽管事件只包含可能导致信息丢失的已处理数据。
    更糟糕的是:由于事件数据已经计算出来,我也放弃了通过重播事件来纠正错误的业务逻辑的可能性。

示例:从某些数据计算度量标准。
要么我必须计算两次公式(一次在域模型中,一次在投影中)
或者我必须在发送事件并将其包括在内之前计算它。

回答

4

控制的流程通常是这样的:

  • 命令被发送到在所述命令的命令处理程序和属性是预先验证,如身份指向现有实体和所有强制信息存在,并且在正确的格式
  • 命令处理程序检索来自库的集合(通过读取事件流,但是这并不重要),并调用根据需要由该命令
  • 骨料做什么总法(S)方法必须确保它们的参数和aggre门状态相互允许执行操作。

  • 总计方法,然后创建一个事件,并呼吁该WhenApply方法来处理事件

  • 事件处理变异聚集状态,没有逻辑存在!然后

  • 控制流返回到命令处理程序,并坚持所有的新事件在店里

进一步的动作都与预测。

在应用事件之前,将不变保护又称业务逻辑放入聚合事件的原因是,事件生成时不会退回。这件事已经发生了。你不能否认应用一个事件。考虑从事件流中恢复聚合时重放事件(从存储库中读取),如果有一天您决定在那里使用if-throw组合,该如何工作?

因此,简而言之:

    被发送的命令之前被施加
  • 初始逻辑
  • 一些附加的逻辑是在命令处理程序在聚合方法
  • 骨料保护(很可能是也命令处理程序)
  • 在事件处理程序没有逻辑,只有状态突变

没有人EV呃说事件采购会帮助你解决计算中的问题。为了建立一个额外的安全网络,你可能想要保存命令,但是你将不得不发布补偿事件或截断流,这实际上并不是你想要做的。

+0

修复计算问题被一些人明确描述为一项好处。请参阅此处:“修复错误您可能会发现导致系统计算错误值的编码错误,而不是修复编码错误并对存储的数据项执行有风险的手动调整,您可以修复编码错误并重放事件流,以便系统根据新版本的代码正确计算值。“ (从https://msdn.microsoft.com/en-us/library/jj591559.aspx#sec2) 但除此之外,谢谢澄清。 – hybridtupel

+1

如果计算发生在读取模型的投影中 - 这确实有意义。事件中的计算适用于变更聚合状态不变。 –

0

我想你在你的聚合根中有一些状态。这应该包含关于您的业务的逻辑。所以它应该有足够的数据来根据命令创建事件。
此事件的消费者(查询模型)进行计算。所以如果意图是计算平均值,它必须设法以给定的方式存储自己。
我做了类似的事情。一旦它是业务逻辑的一部分,它就在Aggregate中,一旦它在Query模型中,因为它不是业务逻辑的一部分,而是更多的度量计算。
不要害怕将数据存储在多个地方。一致性的责任应该委托给事件分发,而不是你的业务逻辑。

+0

你有一些图形你怎么做到的? – hybridtupel

+0

我不太清楚最后一部分,所以你说你拆分逻辑,一部分在聚合中,另一部分在查询模型中? – hybridtupel

+0

这里是很好的文章,其中描述了CQRS/ES。 https://msdn.microsoft.com/en-us/library/jj591559.aspx – hellxcz