gpt4 book ai didi

asp.net-mvc - 在哪里引发与持久性相关的域事件-服务,存储库或UI?

转载 作者:行者123 更新时间:2023-12-03 08:49:48 25 4
gpt4 key购买 nike

我的ASP.NET MVC3 / NHibernate应用程序需要启动并处理与我的域对象有关的各种事件。例如,Order对象可能具有OrderStatusChangedNoteCreatedForOrder之类的事件。在大多数情况下,这些事件会导致发送电子邮件,因此我不能仅仅将它们留在MVC应用中。
我已经阅读了Udi Dahan的Domain Events以及有关如何执行此类操作的许多其他想法,我决定使用基于NServiceBus的主机来处理事件消息。我已经完成了一些概念验证测试,而且看来效果很好。
我的问题是,哪个应用程序层应实际引发事件。我不想在事件对象成功持久存储之前触发事件(如果持久存储失败,则无法发送电子邮件说明已创建便笺)。
另一个担心是,在某些情况下,事件与聚合根下方的对象相关。在上面的示例中,通过将Note添加到Order.Notes集合并保存顺序来保存它。这就带来了一个问题,因为这使得很难评估保存Order时应触发哪些事件。我想避免保存对象的当前副本并在保存更新的副本之前查找差异。

  • UI是否适合引发这些事件?它知道发生了什么事件,并且只有在成功使服务层保存对象之后才能触发它们。让 Controller 触发域事件似乎有些不对劲。
  • 存储库在成功持久化后是否应该触发事件?
  • 我是否应该将事件完全分开,让存储库存储一个Event对象,该对象然后由轮询器服务拾取,然后变成NServiceBus的事件(或直接从轮询器服务处理)?
  • 有更好的方法吗?也许让我的域对象将仅在对象持久后才由服务层触发的事件排队?
  • 更新:我有一个服务层,但是让它经历一个比较过程来确定在保存给定聚合根时应该触发哪些事件似乎很麻烦和过度。因为其中一些事件是细粒度的(例如“订单状态已更改”),所以我认为我必须检索对象的数据库副本,比较属性以创建事件,保存新对象,然后在以下情况下将事件发送到NServiceBus保存操作成功完成。

  • 更新资料
    在我在下面发布答案( way below)之后,我最终要做的是在我的域实体中构建一个 EventQueue属性,该属性是 List<IDomainEvent>。然后,我添加事件作为对 Realm 的更改,这值得我去做,这使我能够将逻辑保持在域内,因为我根据实体内部发生的事件触发事件,所以我认为这是适当的。
    然后,当我将对象保留在服务层中时,我将处理该队列,然后将事件实际发送到服务总线。最初,我打算使用使用身份PK的旧数据库,因此我必须对这些事件进行后处理以填充实体的ID,但最终我决定切换到 Guid.Comb PK,这使我可以跳过此步骤。

    最佳答案

    我的解决方案是在域层和服务层中引发事件。

    您的网域:

    public class Order
    {
    public void ChangeStatus(OrderStatus status)
    {
    // change status
    this.Status = status;
    DomainEvent.Raise(new OrderStatusChanged { OrderId = Id, Status = status });
    }

    public void AddNote(string note)
    {
    // add note
    this.Notes.Add(note)
    DomainEvent.Raise(new NoteCreatedForOrder { OrderId = Id, Note = note });
    }
    }

    您的服务:
    public class OrderService
    {
    public void SubmitOrder(int orderId, OrderStatus status, string note)
    {
    OrderStatusChanged orderStatusChanged = null;
    NoteCreatedForOrder noteCreatedForOrder = null;

    DomainEvent.Register<OrderStatusChanged>(x => orderStatusChanged = x);
    DomainEvent.Register<NoteCreatedForOrder>(x => noteCreatedForOrder = x);

    using (var uow = UnitOfWork.Start())
    {
    var order = orderRepository.Load(orderId);
    order.ChangeStatus(status);
    order.AddNote(note);
    uow.Commit(); // commit to persist order
    }

    if (orderStatusChanged != null)
    {
    // something like this
    serviceBus.Publish(orderStatusChanged);
    }

    if (noteCreatedForOrder!= null)
    {
    // something like this
    serviceBus.Publish(noteCreatedForOrder);
    }
    }
    }

    关于asp.net-mvc - 在哪里引发与持久性相关的域事件-服务,存储库或UI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5886174/

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