Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IRequestHandler return void

Please see the code below:

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

It works as expected i.e. the hander is reached and returns true. How do I deal with the scenario where the handler returns nothing? I want to do this:

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

I have spent the last two hours Googling this. For example, I have looked here: Register a MediatR pipeline with void/Task response and here: https://github.com/jbogard/MediatR/issues/230.

like image 509
w0051977 Avatar asked Feb 14 '19 10:02

w0051977


3 Answers

Generally speaking, if a Task based method does not return anything you can return a completed Task

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

Now, in MediatR terms a value needs te be returned. In case of no value you can use Unit:

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

or, in case of some async code somewhere

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

        return Unit.Value;
    }

The class signature should then be:

public class CreatePersonHandler : IRequestHandler<CreatePersonCommand>

which is short for

public class CreatePersonHandler : IRequestHandler<CreatePersonCommand, Unit>
like image 200
Peter Bons Avatar answered Oct 13 '22 14:10

Peter Bons


In CreatePersonCommand , IRequest shouldn't have any response type specified :

public record CreatePersonCommand : IRequest

And in PersonCommandHandler, IRequestHandler would be like this :

public class PersonCommandHandler: IRequestHandler<PersonCommandHandler>

And then in your handle method :

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

    return Unit.Value;
}
like image 13
Kaveh Naseri Avatar answered Oct 13 '22 14:10

Kaveh Naseri


Workaround solution for anyone who doesn't want to use Unit for some reason. You can create class named as VoidResult or EmptyResult then use it as return for all requests that returns nothing.

public class CreatePersonHandler : IRequestHandler<CreatePersonCommand, VoidResult>
like image 4
M.Erkan Çam Avatar answered Oct 13 '22 15:10

M.Erkan Çam