【问题标题】:IRequestHandler return voidIRequestHandler 返回无效
【发布时间】:2019-07-08 07:41:43
【问题描述】:

请看下面的代码:

public class CreatePersonHandler
    : IRequestHandler<CreatePersonCommand,bool>
{
    public async Task<bool> Handle(CreatePersonCommand message, CancellationToken cancellationToken)
    {
        return true;
    }
}

它按预期工作,即到达处理程序并返回 true。如何处理处理程序不返回任何内容的情况?我想这样做:

public async void Handle(CreatePersonCommand message, CancellationToken cancellationToken)
{
    //don't return anything
}

我在过去的两个小时里用谷歌搜索了这个。例如,我看过这里:Register a MediatR pipeline with void/Task response 和这里:https://github.com/jbogard/MediatR/issues/230

【问题讨论】:

标签: c# async-await task cqrs mediatr


【解决方案1】:

一般来说,如果基于 Task 的方法没有返回任何内容,您可以返回 completed Task

    public Task Handle(CreatePersonCommand message, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

现在,在 MediatR 术语中,需要返回一个值。如果没有价值可以使用Unit:

    public Task<Unit> Handle(CreatePersonCommand message, CancellationToken cancellationToken)
    {
        return Task.FromResult(Unit.Value);
    }

或者,如果某处有一些异步代码

    public async Task<Unit> Handle(CreatePersonCommand message, CancellationToken cancellationToken)
    {
        await Task.Delay(100);

        return Unit.Value;
    }

类签名应该是:

public class CreatePersonHandler : IRequestHandler<CreatePersonCommand>

简称

public class CreatePersonHandler : IRequestHandler<CreatePersonCommand, Unit>

【讨论】:

  • 谢谢。这个类继承自一个基类,如下所示: public class IdentifiedCommandHandler : IRequestHandler, R> where T : IRequest。有什么我可以在这里做的吗?即我需要第二个通用参数。
  • 如何测试函数是否成功完成使用:Unit.Value; ?
  • @w0051977 它没有用于测试Unit.Value,因为它是基于任务的 void 的 MediatR 表示。如果你查看源代码,你会发现它有a default value assigned
  • 谢谢。你会不测试这个方法吗?该方法包含在没有实例变量的类中,并且不返回任何内容。
【解决方案2】:

CreatePersonCommand 中,IRequest 不应指定任何响应类型:

public record CreatePersonCommand : IRequest

PersonCommandHandlerIRequestHandler 会是这样的:

public class PersonCommandHandler: IRequestHandler<PersonCommandHandler>

然后在您的handle 方法中:

public async Task<Unit> Handle(CreatePersonCommand request, CancellationToken cancellationToken)
{
    // Some Code 

    return Unit.Value;
}

【讨论】:

    【解决方案3】:

    任何出于某种原因不想使用 Unit 的人的解决方案。您可以创建名为 VoidResult 或 EmptyResult 的类,然后将其用作所有不返回任何请求的返回。

    public class CreatePersonHandler : IRequestHandler<CreatePersonCommand, VoidResult>
    

    【讨论】:

      【解决方案4】:

      还有另一个名为 AsyncRequestHandler 的抽象类,它是异步处理请求但不返回响应的处理程序的包装类。

      public class CreatePersonHandler : AsyncRequestHandler<CreatePersonCommand>
      

      【讨论】:

        猜你喜欢
        • 2012-03-21
        • 2011-10-26
        • 2012-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-28
        • 2021-05-31
        相关资源
        最近更新 更多