MessagePipe icon indicating copy to clipboard operation
MessagePipe copied to clipboard

Can we have smoother usage in RequestHandlers as in MediatR?

Open jonathanperis opened this issue 3 years ago • 1 comments

MessagePipe is just wonderful. His performance is unmatched by competitors today. I used it in an experiment project of mine and the difference in load tests is noticeable.

The only thing that bothered me when I used it was the following: In a scenario of an application using CQRS, the code using MessagePipe is more coupled and repetitive than with MediatR.

I'll give an example: This is a gRPC service using MagicOnion + MessagePipe that I used in my studies:


namespace Cpnucleo.GRPC.Services;

[Authorize]
public class SistemaGrpcService : ServiceBase<ISistemaGrpcService>, ISistemaGrpcService
{
    private readonly IAsyncRequestHandler<CreateSistemaCommand, CreateSistemaResponse> _createSistemaCommand;
    private readonly IAsyncRequestHandler<ListSistemaQuery, ListSistemaResponse> _listSistemaQuery;
    private readonly IAsyncRequestHandler<GetSistemaQuery, GetSistemaResponse> _getSistemaQuery;
    private readonly IAsyncRequestHandler<RemoveSistemaCommand, RemoveSistemaResponse> _removeSistemaCommand;
    private readonly IAsyncRequestHandler<UpdateSistemaCommand, UpdateSistemaResponse> _updateSistemaCommand;

    public SistemaGrpcService(IAsyncRequestHandler<CreateSistemaCommand, CreateSistemaResponse> createSistemaCommand,
                              IAsyncRequestHandler<ListSistemaQuery, ListSistemaResponse> listSistemaQuery,
                              IAsyncRequestHandler<GetSistemaQuery, GetSistemaResponse> getSistemaQuery,
                              IAsyncRequestHandler<RemoveSistemaCommand, RemoveSistemaResponse> removeSistemaCommand,
                              IAsyncRequestHandler<UpdateSistemaCommand, UpdateSistemaResponse> updateSistemaCommand)
    {
        _createSistemaCommand = createSistemaCommand;
        _listSistemaQuery = listSistemaQuery;
        _getSistemaQuery = getSistemaQuery;
        _removeSistemaCommand = removeSistemaCommand;
        _updateSistemaCommand = updateSistemaCommand;
    }

    public async UnaryResult<OperationResult> AddAsync(CreateSistemaCommand command)
    {
        return await _createSistemaCommand.InvokeAsync(command);
    }

    public async UnaryResult<ListSistemaViewModel> AllAsync(ListSistemaQuery query)
    {
        return await _listSistemaQuery.InvokeAsync(query);
    }

    public async UnaryResult<GetSistemaViewModel> GetAsync(GetSistemaQuery query)
    {
        return await _getSistemaQuery.InvokeAsync(query);
    }

    public async UnaryResult<OperationResult> RemoveAsync(RemoveSistemaCommand command)
    {
        return await _removeSistemaCommand.InvokeAsync(command);
    }

    public async UnaryResult<OperationResult> UpdateAsync(UpdateSistemaCommand command)
    {
        return await _updateSistemaCommand.InvokeAsync(command);
    }
}

It works very well, as expected. The only issue in this implementation focused on CQRS is that the modules need to be unique for each request (Commands/Queries and their responses) end up making the implementation very repetitive and verbose.

This is the same gRPC service using MagicOnion + MediatR:


namespace Cpnucleo.GRPC.Services;

[Authorize]
public class SistemaGrpcService : ServiceBase<ISistemaGrpcService>, ISistemaGrpcService
{
    private readonly IMediator _mediator;

    public SistemaGrpcService(IMediator mediator)
    {
        _mediator = mediator;
    }

    public async UnaryResult<OperationResult> AddAsync(CreateSistemaCommand command)
    {
        return await _mediator.Send(command);
    }
     
    public async UnaryResult<ListSistemaViewModel> AllAsync(ListSistemaQuery query)
    {
        return await _mediator.Send(query);
    }
  
    public async UnaryResult<GetSistemaViewModel> GetAsync(GetSistemaQuery query)
    {
        return await _mediator.Send(query);
    }
    
    public async UnaryResult<OperationResult> RemoveAsync(RemoveSistemaCommand command)
    {
        return await _mediator.Send(command);
    }
 
    public async UnaryResult<OperationResult> UpdateAsync(UpdateSistemaCommand command)
    {
        return await _mediator.Send(command);
    }
}

Wouldn't it be possible to have a RequestHandler in MagicOnion that works similarly to how MediatR works for cases like the one I mentioned above?

jonathanperis avatar Jun 21 '22 16:06 jonathanperis

good question.

sgf avatar Sep 20 '22 18:09 sgf