发送命令后更新UI

本文关键字:更新 UI 命令 | 更新日期: 2023-09-27 18:05:15

我正在努力解决这个架构问题,我们的系统使用NService总线,并使用NEventStore和NES实现DDD和EventSourcing。客户端应用程序是WPF

我仍然不能决定什么是更新UI的最佳实践,例如:我有一个UI来创建(Batch {Id, StartDate, EndDate等}),在用户点击保存后,我发送一个命令(CreateBatch),

Bus.Send<CreateBatch> (batch => {batch.Id = Guid.NewGuid(); .... etc });
现在

选项# 1


我是否应该按照以下方式登记回复?

private void btnSave_Click(object sender,EventsArg e){
    Bus.Send<CreateBatch> (batch => {batch.Id = Guid.NewGuid(); .... etc })
       .Register<int>(c=> { 
                     MessageBox.Show("Command Succeded");
                     Close();});
}

和服务器端:

public void Hanlde(CreateBatch cmd){
   //initiate aggregate and save it.
   Bus.Return( /*What ?? Success Code?*/);
}

在这种情况下,如何处理错误?(验证错误,例如在同一日期已经有一批开始?),因为您只能返回int或string !!

选项# 2:


发送命令,关闭窗口,假装记录已添加到主网格中,直到用户刷新网格并从ReadModel数据库中获得真实的记录,或者发现记录尚未添加,不知道发生了什么!!

private void btnSave_Click(object sender,EventsArg e){
    Bus.Send<CreateBatch> (batch => {batch.Id = Guid.NewGuid(); .... etc });
    Close();
}

选项# 3


发送命令,关闭窗口,假装记录被添加到主网格中,但将其标记为(正在进行中),等待(BatchCreated)事件到达,检查它是否与我们之前发送的批id相同,然后将记录标记为在网格中持续存在

private void btnSave_Click(object sender,EventsArg e){
    Bus.Send<CreateBatch> (batch => {batch.Id = Guid.NewGuid(); .... etc });
    Close();
}

public class BatchHandler : IHandleMessages<BatchCreated>
{
    public void Handle(BatchCreated evnt)
    {
     if(SomeCachForSentIDS.Contains(evnt.BatchId)
         ///Code to refresh the row in the grid and reflect that the command succeeded.
    }
}

如果你有任何更好的选择,或者对上述选项有建议,甚至是一些关于如何处理这种情况的链接,我将不胜感激。

谢谢。

发送命令后更新UI

在这样的解决方案中引入消息传递时,一个重要的原则是确保命令几乎不会失败(正如评论中提到的@ ope)。

这意味着在发送消息之前,应该在客户端执行所有类型的验证检查。

现在,即使在执行客户端验证时,您仍然可能暴露于竞争条件—两个用户同时创建一个批处理,这些批处理以某种方式相互冲突。处理这个问题的方法是澄清用户意图,可能会改变任务的性质以及UI,使新命令即使在并行处理的情况下也能成功。

作为解决方案的一个简单尝试,您可以重新定义逻辑以为批处理引入一个新状态-例如"冲突",如果另一个批处理同时启动,则将设置该状态。这样命令就成功了(创建了批处理),然后使用SignalR之类的东西将此状态的通知推回给用户,以便他们可以着手纠正它。

最后,您可能需要完全重新考虑消息传递的使用,而只使用简单的两层同步解决方案。

如何为异步消息传递设计这些用户界面(特别是在我们被灌输了CRUD思维方式之后)是这些系统中最重要的问题。

我100%同意Udi的评估。此外,您的问题似乎对确切的业务需求相当不透明,但是CreateBatch命令和BatchCreated事件名称的CRUD性质使我怀疑它是否真的是与消息传递有关的有用的事情。

如果你发现自己在一个情况下,你必须等待CreateBatch完成,所以你可以对它做更多的事情,也许你不应该有CreateBatch。也许你应该只是在"本地"创建一些东西(这可能意味着JavaScript中的客户端,或者像Udi建议的那样,在最简单的2层数据库模型中),然后发送一个命令来做真正的工作(ProcessBatch也许?)一旦一切完成。

毕竟,消息传递的目标并不是将web层与数据库请求完全分离。