代码之家  ›  专栏  ›  技术社区  ›  Dheeraj Kumar

CQRS-在C#,ASP.net内核中使用Mediatr创建BaseCommandHandler

  •  2
  • Dheeraj Kumar  · 技术社区  · 7 年前

    所以我知道了 Mediatr 由Jimmy Bogard创作,我们取得的成就让我非常惊讶 CQRS 模式使用 Mediatr .

    我开始在我的应用程序中实现它,然后我意识到我可能有数百个 Entities DRY . 所以我开始编写基本命令和处理程序。

    public abstract class CreateBaseCommand : IRequest
    {    
    }
    
    public abstract class DeleteBaseCommand : IRequest
    {
    }  //... and so on.
    

    以及各自的处理程序。

    public abstract class CreateBaseHandler : IRequestHandler<CreateBaseCommand>
    {
    }
    
    public abstract class DeleteBaseCommandHandler : IRequestHandler<DeleteBaseCommand>
    {
    }//... and so on.
    

        public abstract class BaseCommand : IRequest
        { 
           int CommandType
        }
    
        public abstract class BaseCommandHandler : IRequestHandler<BaseCommand>
        {
           public Task<Unit> Handle(BaseCommand request, CancellationToken cancellationToken)
           {
            if (CommandType == 0)
            {
                // Create entity
            }
            if (CommandType == 1)
            {
                // Update entity
            }//.. and so on
          }
        }
    

    我想知道是否有更有效的方法来做到这一点,我不太相信使用的想法 CommandType 还有一个 handle 方法来执行所有CRUD操作。

    这是一个好方法,还是应该为每个域实体单独设置一组命令?

    1 回复  |  直到 7 年前
        1
  •  6
  •   Brad Irby    7 年前

    真正的问题是,您是从数据模型的角度来考虑这一点的,而不是从域模型的角度。您正在为每个表行创建一个命令,而您应该为每个业务想法创建一个命令。

    例如,假设您正在编写一个零售系统,并为注册用户创建一个新订单,该订单有5行项目。从数据模型的角度来看,需要为订单发送1个create命令,为行项目发送5个create命令。应该做的是发送一个命令AddNewOrderCommand并让用户类处理它。然后,用户类方法创建新的订单数据库行和所有行项目。如何添加顺序(创建哪些行等)现在封装在它所属的方法中,而不是您的命令体系结构中。

    您的应用程序是否使用域驱动设计?如果不是,你应该考虑它,因为它非常复杂的系统,如果你有数百个实体的机会是好的,这有资格作为一个复杂的系统。用DDD的说法,上面的用户被调用,聚合根、订单和行项目只是实体。您没有为实体创建命令,只为聚合根创建命令(请注意,类有时可以是聚合根,也可以是另一个聚合根中的普通实体。发生这种情况的原因以及如何处理超出了本问题的范围)

    看看你的模型,找出那些没有意义的东西,除非它们属于其他东西。例如,上面示例中的行项目。在我的数据库中有一个与订单无关的行项目是没有意义的。因此,所有行项目都应按订单创建。拥有一个没有用户关联的订单也是没有意义的。因此,用户应该创建订单。然而,用户似乎是金字塔的顶端,因此它是聚合根,确实需要一个Create命令。

    如果你分析你的领域,你会发现你不需要那么多的Create命令,所以问题就消失了。