I would like to be able to "Execute" a handler with it's pipeline without having the abstraction between a Request and it's handler.
I've seen that in a lot of cases the abstraction between a handler and a request only gives friction (go to implementation). So I would like to propose a way to "Execute" a handler via Mediator for the Pipeline.
Something like:
var pingHandler = new PingHandler(output);
var response = await mediator.Execute(pingHandler.Handle, new Ping { Message = "Ping" });
With the following interface.
public delegate Task<TResponse> RequestHandlerHandleDelegate<TRequest, TResponse>(
TRequest request, CancellationToken cancellation = default)
where TRequest : IRequest<TResponse>;
public interface IMediator
{
Task<TResponse> Execute<TRequest, TResponse>(
RequestHandlerHandleDelegate<TRequest, TResponse> handler,
TRequest request,
CancellationToken cancellationToken = default)
where TRequest : IRequest<TResponse>;
...
// In the RequestHandlerWrapper something like:
public Task<TResponse> HandleWithHandler(IRequest<TResponse> request, CancellationToken cancellationToken,
ServiceFactory serviceFactory, RequestHandlerHandleDelegate<TRequest, TResponse> endHandler)
{
Task<TResponse> Handler() => endHandler != null ? endHandler((TRequest)request) : GetHandler<IRequestHandler<TRequest, TResponse>>(serviceFactory).Handle((TRequest)request, cancellationToken);
return serviceFactory
.GetInstances<IPipelineBehavior<TRequest, TResponse>>()
.Reverse()
.Aggregate((RequestHandlerDelegate<TResponse>)Handler, (next, pipeline) => () => pipeline.Handle((TRequest)request, cancellationToken, next))();
}
I don't know whether you want this to be included in this library (as it kind of defeats the purpose of a Mediator), but I see a lot of cases where it's not really added because it's a Mediator but because of the Request/Command pipeline.
I'm ok to fix my POC and create a PR if it's seen as a good addition :).
This is purely my opinion and im (obviously) not related to the project in any way.
I dont think that this really belongs in the core project. One option would be to implement a custom mediator and expose your own interface if you really need the functionality. There are a couple of samples which you have probably already seen. Wouldn't this solve the problem?
Regarding the navigation issue (when not debugging): I think I saw the tip from Jimmy some time ago. I nowadays name my requests in such a way that it is easy to navigate to the handlers.
PingRequest => PingRequestHandler. PongCommand => PongCommandHandler. You get the idea. Highlight the request class, CTRL+T and bam your handler is right there in the Go To dropdown.
Most helpful comment
This is purely my opinion and im (obviously) not related to the project in any way.
I dont think that this really belongs in the core project. One option would be to implement a custom mediator and expose your own interface if you really need the functionality. There are a couple of samples which you have probably already seen. Wouldn't this solve the problem?
Regarding the navigation issue (when not debugging): I think I saw the tip from Jimmy some time ago. I nowadays name my requests in such a way that it is easy to navigate to the handlers.
PingRequest => PingRequestHandler. PongCommand => PongCommandHandler. You get the idea. Highlight the request class, CTRL+T and bam your handler is right there in the Go To dropdown.