最近在开发过程中,遇到了一个场景,甚是棘手,在这里分享一下。希望大家脑洞大开一起来想一下解决思路。鄙人也想了一个方案拿出来和大家一起探讨一下是否合理。一、简单介绍一下涉及的对象概念 工作单元:维护变化的对象列表,在整块业务逻辑处理完全之后一次性写入到数据库中。 领域事件:领域 ...
最近在开发过程中,遇到了一个场景,甚是棘手,在这里分享一下。希望大家脑洞大开一起来想一下解决思路。鄙人也想了一个方案拿出来和大家一起探讨一下是否合理。
一、简单介绍一下涉及的对象概念
工作单元:维护变化的对象列表,在整块业务逻辑处理完全之后一次性写入到数据库中。
领域事件:领域对象本身发生某些变化时,发布的通知事件,告诉订阅者处理相关流程。
二、问题来了
我认为最合理的领域事件的触发点应该设计在领域对象内部,那么问题来了。当这个领域对象发生变化的上下文是一个复杂的业务场景,整个流程中会涉及到多个领域对象,所以需要通过工作单元来保证数据写入的一致性。此时其中各个产生变化的领域对象的领域事件如果实时被发布出去,那么当工作单元在最终提交到数据库时,如果产生了回滚,那么会导致发布了错误的领域事件,产生未知的后果。
三、问题分析
我能够想到的方案是,这里领域事件的发布也通过一个类似于工作单元一样的概念进行持续的管理,在领域对象中的发布只是做一个记录,只有在工作单元提交成功之后,才实际发布其中所有的领域事件。
四、说干就干
实现类:
1 public class DomainEventConsistentQueue : IDisposable 2 { 3 private readonly List<IDomainEvent> _domainEvents = new List<IDomainEvent>(); 4 private bool _publishing = false; 5 6 public void RegisterEvent(IDomainEvent domainEvent) 7 { 8 if (_publishing) 9 {10 throw new ApplicationException("当前事件一致性队列已被发布,无法添加新的事件!");11 }12 13 if (_domainEvents.Any(ent => ent == domainEvent)) //防止相同事件被重复添加14 return;15 16 _domainEvents.Add(domainEvent);17 }18 19 public void Clear()20 {21 _domainEvents.Clear();22 _publishing = false;23 }24 25 public void PublishEvents()26 {27 if (_publishing)28 {29 return;30 }31 32 if (_domainEvents == null)33 return;34 35 try36 {37 _publishing = true;38 foreach (var domainEvent in _domainEvents)39 {40 DomainEventBus.Instance().Publish(domainEvent);41 }42 }43 finally44 {45 Clear();46 }47 }48 49 public void Dispose()50 {51 Clear();52 }53 }
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:DDD设计中的Unitwork与DomainEvent如何相容?
关键词:dom
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。