jbogard / MediatR

Simple, unambitious mediator implementation in .NET
Apache License 2.0
10.91k stars 1.16k forks source link

Covariant IRequest Handler #945

Closed jfgauron closed 11 months ago

jfgauron commented 11 months ago

Hi, I would like to have a single IRequestHandler that take cares of all my IRequest commands / queries. I was able to achieve this with INotificationHandler but the very same example with IRequest instead of INotification fails, so I assume there is a technical reason for that? I would need to make it work with IRequest because I need to return a value of a specific type depending on the IRequest sent.

1) Am I correct to assume that it is not possible to do? 2) If yes to previous question, I'd be curious to know what is the reason?

Also, I've found that I was able to achieve what I was looking to do using Behavior, here is an example of what I did:

using MediatR;

namespace MediatRDebug;

public interface ICommand<TResponse> : IRequest<TResponse>
{
    public Task<TResponse> Execute();
}

public class MyPipeline<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : ICommand<TResponse>
{

    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        return await request.Execute();
    }
}

public class MyCommand : ICommand<string>
{
    public Task<string> Execute()
    {
        return Task.FromResult("This is a test");
    }
}

Now, it works as I would expect, but it feels kind of weird using the pipeline like that. Am I doing something wrong here or this would be the recommended way to achieve what I'm trying to do?

Thanks.

jbogard commented 11 months ago

Probably my best answer here is "don't use MediatR". It was not designed for such a scenario. You're probably better off building your own mediator class and handling the generic funny business yourself.