Can we have smoother usage in RequestHandlers as in MediatR?
See original GitHub issueMessagePipe 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 MessagePipe that works similarly to how MediatR works for cases like the one I mentioned above?
Issue Analytics
- State:
- Created a year ago
- Reactions:7
- Comments:5 (1 by maintainers)
See PR #101 and its unit tests!
Interesting request / topic.
Depends on the Query / Command type => Handler type => Response type. This should be registered somewhere or through runtime reflection (partly) accomplished. MediatR does this through tight coupling with DI/IoC and coupling the Request Type hard to the Response type.
Wonder if there will be a solution that will be even fast as current implementation(s).