从另一个命令Handle()方法中调用命令

您好我正在使用Simple Injector DI库并且已经关注了一些关于围绕命令模式设计的架构模型的非常有趣的材料:

  • 同时……在我的架构的命令端
  • 同时……在我的架构的查询方面

容器将管理UnitOfWork的生命周期,我使用命令来执行数据库的特定function。

我的问题是,如果我有一个命令,例如AddNewCustomerCommand ,它反过来又对另一个服务执行另一个调用(即发送文本消息),从设计的角度来看这是可以接受的,还是应该在更高的层次上完成,如果是的话怎么做到最好?

示例代码如下:

 public class AddNewBusinessUnitHandler : ICommandHandler { private IUnitOfWork uow; private ICommandHandler otherHandler; AddNewBusinessUnitHandler(IUnitOfWork uow, ICommandHandler otherHandler) { this.uow = uow; this.otherHandler = otherHandler; } public void Handle(AddBusinessUnitCommand command) { var businessUnit = new BusinessUnit() { Name = command.BusinessUnitName, Address = command.BusinessUnitAddress }; var otherCommand = new OtherServiceCommand() { welcomePostTo = command.BusinessUnitName }; uow.BusinessUnitRepository.Add(businessUnit); this.otherHandler.Handle(otherCommand); } } 

它取决于(业务)命令的体系结构视图,但在用例和命令之间进行一对一映射是很自然的。 在这种情况下,表示层应该(在单个用户操作期间,例如按钮单击)只执行创建命令并执行它。 此外,它应该只执行单个命令,而不是更多。 执行该用例所需的一切都应该由该命令完成。

也就是说,发送文本消息,写入数据库,进行复杂的计算,与Web服务进行通信以及操作业务需求所需的其他所有内容都应该在该命令的上下文中完成(或者可能在以后排队等待)。 不是之前,而是之后,因为它是以表示不可知的方式表示要求的命令。

这并不意味着命令处理程序本身应该完成所有这些。 将很多逻辑移动到处理程序所依赖的其他服务是很自然的。 所以我可以想象你的处理程序取决于ITextMessageSender接口。

另一个讨论是命令处理程序是否应该依赖于其他依赖命令处理程序。 当您查看用例时,大用例不一定包含多个较小的子用例,因此从这个意义上来说并不奇怪。 同样,命令和用例之间将存在一对一的映射。

但是,请注意,依赖于彼此的嵌套命令处理程序的深度依赖关系图可能会使代码导航变得复杂,因此请仔细查看。 例如,注入ITextSessageSender而不是使用ICommandHandler可能更好。

允许处理程序嵌套的另一个缺点是它使基础结构的东西变得复杂一些。 例如,在使用添加事务行为的装饰器包装命令处理程序时,需要确保嵌套处理程序在与最外层处理程序相同的事务中运行。 今天我碰巧帮助了我的客户。 这并不难,但需要一点时间才能搞清楚。 对于死锁检测这样的事情也是如此,因为这也在事务的边界处运行。

此外,死锁检测是一个很好的例子来展示这个命令/处理程序模式的强大function,因为几乎所有其他架构风格都会使插入这种行为变得不可能。 看一下这篇文章中的DeadlockRetryCommandHandlerDecorator类来看一个例子。