c# – 具有持久性无知对象的持久性和域事件
我一直在研究与
domain events结合的域驱动设计.我非常喜欢这些事件提供的关注点的分离.我遇到了持久化域对象和提升域事件的问题.我想在域对象中引发事件,但我希望它们是持久性无知的.
我用这个Checkout方法创建了一个基本的ShoppingCartService: public void Checkout(IEnumerable<ShoppingCartItem> cart,Customer customer) { var order = new Order(cart,customer); _orderRepositorty.Add(order); _unitOfWork.Commit(); } 在此示例中,Order的构造函数将引发OrderCreated事件,该事件可由某些处理程序处理.但是,我不希望在实体尚未持久化或持久化以某种方式失败时引发这些事件. 为了解决这个问题,我找到了几个解决方案: 1.提升服务中的事件: 我可以在服务中引发事件,而不是在域对象中引发事件.在这种情况下,Checkout方法将引发OrderCreated事件.这种方法的一个缺点是,通过查看Order域对象,不清楚哪些事件是由哪些方法引发的.此外,开发人员必须记住在其他地方创建订单时提出事件.感觉不对劲. 2.队列域事件 另一个选项是对域事件进行排队,并在保持成功时引发它们.这可以通过using语句来实现,例如: using (DomainEvents.QueueEvents<OrderCreated>()) { var order = new Order(cart,customer); _orderRepositorty.Add(order); _unitOfWork.Commit(); } QueueEvents< T>方法将布尔值设置为true,并将DomainEvents.Raise< T>设置为method会对事件进行排队,而不是直接执行它.在QueueEvent< T>的dispose回调中,执行排队事件以确保已经发生持久化.这似乎相当棘手,它需要服务知道域对象中引发了哪个事件.在我提供的示例中,它也只支持一种类型的事件,但是,这可以解决. 3.坚持域名活动 我可以使用域事件来持久化对象.这似乎没问题,除了持久化对象的事件处理程序应首先执行这一事实,但我在某处读到域事件不应该依赖于特定的执行顺序.也许这不是那么重要,域事件可能以某种方式知道处理程序应该执行的顺序.例如:假设我有一个定义域事件处理程序的接口,实现将如下所示: public class NotifyCustomer : IDomainEventHandler<OrderCreated> { public void Handle(OrderCreated args) { // ... } } 当我想处理持久使用事件处理程序时,我会创建另一个处理程序,派生自同一个接口: public class PersistOrder : IDomainEventHandler<OrderCreated> { public void Handle(OrderCreated args) { // ... } } } 现在NotifyCustomer行为取决于数据库中保存的顺序,因此PersistOrder事件处理程序应首先执行.是否可以接受这些处理程序引入一个属性,例如表明它们执行的顺序?快速执行DomainEvents.Raise< OrderCreated>()方法: foreach (var handler in Container.ResolveAll<IDomainEventHandler<OrderCreated>>().OrderBy(h => h.Order)) { handler.Handle(args); } 现在我的问题是,我还有其他选择吗?我错过了什么吗?您如何看待我提出的解决方案? 解决方法
您的(事务性)事件处理程序在(可能是分布式的)事务中登记,或者在事务提交后发布/处理事件.您的“QueueEvents”解决方案获得了正确的基本想法,但有更优雅的解决方案,例如通过存储库或事件存储发布.举个例子来看看
SimpleCQRS
您可能还会发现这些问题和答案很有用: CQRS: Storing events and publishing them – how do I do this in a safe way? Event Aggregator Error Handling With Rollback 第3点更新:
无论你的坚持方式如何,事件的顺序绝对重要(在一个集合内).
持久化和处理事件是一个单独的问题 – 不要使用事件处理程序持久化.首先坚持,然后处理. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |