首页 > 解决方案 > 作为单个 HTTP 请求的一部分执行顺序 MediatR 命令/查询的最佳实践?

问题描述

我处于创建实体需要其他实体的创建和 ID 的情况,但是,我不确定如何最好地使用MediatR来实现。

例如,假设我有一个用户对象...

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }
    public ICollection<Submission> Submissions { get; set; }
}

提交对象...

public class Submission
{
    public int Id { get; set; }
    public string Reference { get; set; }
    public User User { get; set; }
    public ICollection<QuestionsAndAnswer> QuestionAndAnswers { get; set; }
}

和一个 QuestionAndAnswer 对象。

public class QuestionAndAnswer
{
    public int ID { get; set; }
    public string Question { get; set; }
    public string Answer { get; set; }
    public Submission { get; set; }
}

每个用户可以有多个提交,每个提交都有多个问题和答案。

在这种情况下,用户已经完成了一系列问题,提供了答案,填写了提供联系方式的最终表格,然后将信息提交给 API。在这一点上,我不确定如何使用 MediatR 处理数据,因为必须创建用户,并返回他们的 ID 作为结果来创建提交对象,这反过来又是必需的,以便可以保存问题和答案。

我是否应该实现一个名为 CreateUserWithSubmissionQuestionAndAnswersCommand 的命令,该命令的处理程序然后以某种方式调用三个单独命令的处理程序并按顺序执行它们,如果是这样,如何?

我对如何在不违反 CQRS 的情况下将这个场景实现为单个 HTTPRequest 有点迷茫。我能想到的唯一另一种方法是实现单独的端点,它们分别执行这些任务中的每一个,这需要客户端连续发出和接收三个单独的调用(CreateUser、CreateSubmission、CreateQuestionAndAnswer)?

有人有什么想法吗?

标签: c#asp.net-corecqrscommand-patternmediatr

解决方案


我通常将用户交互/用户故事建模为 MediatR 请求。在大多数情况下,这意味着将单个 HTTP 请求映射到单个 MediatR 请求。

在您的情况下,这将是一个封装提交处理的单个请求,例如ProcessSubmissions. 该请求将包含用户的属性以及提交和相关的问题/答案对。然后,单个处理程序将以正确的顺序保存各个实体。

为了完整起见,此解决方案可能如下所示:

public class ProcessSubmission : IRequest
{
    public User User { get; set; }

    public ICollection<Submission> Submissions { get; set; }
}

public class ProcessSubmissionHandler : IRequestHandler<ProcessSubmission>
{
    public async Task<Unit> Handle(ProcessSubmission request, CancellationToken cancellationToken)
    {
        // Persist the user in the database
        var userId = PersistTheUser(request.User);

        foreach (var submission in request.Submissions)
        {
            // Persist each submission with questions and answers
        }
    }
}

推荐阅读