从另一个命令手柄内调用命令()方法(Calling commands from within ano

2019-07-29 19:41发布

嗨,我使用了简单的注射器 DI库,并已下面讲围绕命令模式设计的建筑模型一些真正有趣的材料:

  • 同时......在我的体系结构的命令侧
  • 同时......在我的体系结构的查询侧

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

我的问题是,如果我有一个命令,例如AddNewCustomerCommand ,这反过来执行另一呼叫到另一个服务(即发送的文本消息),从设计的角度来看这是可接受的或应此在较高水平,并且如果这样做如何更好地做到这一点?

示例代码如下:

public class AddNewBusinessUnitHandler
    : ICommandHandler<AddBusinessUnitCommand>
{
    private IUnitOfWork uow;
    private ICommandHandler<OtherServiceCommand> otherHandler;

    AddNewBusinessUnitHandler(IUnitOfWork uow, 
        ICommandHandler<OtherServiceCommand> 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);
     }
}

Answer 1:

这取决于(业务)命令你的建筑观点,但它是很自然的有之间的一对一的映射用例和命令。 在这种情况下,表示层应该(一个用户操作过程中,如按钮点击)做的无非就是创建命令并执行它。 此外,它应该做的无非是执行一个命令,绝不会。 执行该用例所需的一切,应该由命令来完成。

也就是说,发短信,写入数据库,做复杂的计算,与Web服务通信,和一切你需要操作的业务需求应该是命令的上下文期间完成(或者排队后发生)。 在此之前,而不是之后,因为它是代表的要求,在演示文稿中不可知的方式命令。

这并不意味着该命令处理程序本身应该做的这一切。 这将是很自然得多逻辑转移到其他服务,其中处理依赖于。 所以,我可以想像,一个视你的处理程序ITextMessageSender接口,例如。

另一个讨论的是,如果命令处理程序应该依赖于其他取决于命令处理程序。 当你在使用的情况下,这不是不可能的,大的用例由多个较小的子用例,所以在这个意义上它是不奇怪。 同样,将有一个命令和用例之间的对应关系。

但是,请注意,具有取决于相互嵌套的命令处理程序的深刻依赖关系图,可以通过复杂的代码导航,所以采取这个很好看。 这可能是最好的注入ITextSessageSender而不是使用ICommandHandler<SendTextMessageCommand>例如。

允许处理器筑巢的另一个缺点是,它使做基础的东西更复杂一点。 举例来说,有增加交易行为装饰包命令处理程序时,您需要确保嵌套处理程序在同一个事务中运行的最外面的处理程序。 我正好帮我的客户端今日。 这不是天昏地暗,但需要一点时间来弄清楚。 这同样适用于类似的事情死锁检测,因为这也是在交易的边界运行。

此外,死锁检测是一个很好的例子,显示情况下,该命令/处理模式的力量,因为几乎所有其他的建筑风格将使其无法插件这种行为。 看看在DeadlockRetryCommandHandlerDecorator类文章 ),看一个例子。



文章来源: Calling commands from within another command Handle() method