在CQRS中注册EventHandler

Qui*_*NaN 5 c# events domain-driven-design event-handling cqrs

我正在尝试使用CQRS和DDD为购买域建模,我知道我在域中引发事件,但是当我使用命令时我不知道在哪里注册它们。事件处理程序是否应该在命令处理程序中注册?也许我误会了一些东西。这是我的过程,您可以帮助您正确建模吗?

最终确定采购订单给定命令,然后命令处理程序确定订单(从存储库中获取订单,更改其状态并保存回db),订单完成事件在域模型中发生,然后事件处理程序使用ID及其订单项查找此订单,供应商的联系信息(可能是电子邮件,甚至是外部服务),并通知他新的采购订单。

我的命令和命令处理程序在应用程序层中(事件处理程序也应该在这里吗?)。域层中的域模型,事件和IRepository。基础结构层中的存储库实现。

域模型(跳过大多数属性):

public class PurchaseOrder
{
   public PurchaseOrder(int purchaseOrderID, int supplierID, bool isOrderFinalized)
   {
      PurchaseOrderID = purchaseOrderID;
      SupplierID = supplierID;
      IsOrderFinalized = isOrderFinalized;
   }
   public int PurchaseOrderID { get; private set; }
   public int SupplierID { get; private set; }
   public bool IsOrderFinalized { get; private set; }

   public static PurchaseOrder CreateNew(int supplierID)
   {
      return new PurchaseOrder(0, supplierID, false);
   }

   public void FinalizeOrder()
   {
      IsOrderFinalized = true;
      DomainEvents.Raise(new PurchaseOrderFinalized(PurchaseOrderID));
   }
}
Run Code Online (Sandbox Code Playgroud)

FinalizePurchaseOrder命令

public class FinalizePurchaseOrder : ICommand
{
   public FinalizePurchaseOrder (int purchaseOrderID)
   {
      PurchaseOrderID = purchaseOrderID;
   }
   public int PurchaseOrderID { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

命令处理程序

public class PurchaseOrdersCommandHandler :  ICommandHandler<FinalizePurchaseOrder>
{
    public void Handle(FinalizePurchaseOrder command)
    {
        var purchaseOrder = purchaseOrderRepository.FindByID(command.PurchaseOrderID);
        // Should i register event handler here?
        // DomainEvents.Register<PurchaseOrderFinalized>(PurchaseOrderFinalizedHandler);
        purchaseOrder.FinalizePurchaseOrder();
        purchaseOrderRepository.Save(purchaseOrder);
    }
}
Run Code Online (Sandbox Code Playgroud)

事件和事件处理程序如下所示:

public class PurchaseOrderFinalized 
{
   public PurchaseOrderFinalized(int purchaserOrderID)
   {
      PurchaseOrderID = purchaseOrderID;
   }
}

public void PurchaseOrderFinalizedHandler (PurchaseOrderFinalized evt)
{
   // TODO: Get PurchaseOrder with its line items, and notify supplier about new order
}
Run Code Online (Sandbox Code Playgroud)

tom*_*dge 4

事件处理程序应该在命令处理程序中注册吗?

除非它们是动态的,否则不会。您通常会将它们连接到应用程序的CompositionRoot中。这个想法是,所有连接都在您的应用程序加载时且在“准备好”之前进行。

您在哪里注册命令处理程序?您应该在同一位置注册事件处理程序。

[更新]

有关示例,请参阅https://github.com/gregoryyoung/mr/blob/master/CQRSGui/Global.asax.cs