Without MediatR - Request/response, multiple requests

Arialdo Martini — 29/08/2023 — C# MediatR

Request/response, single handler handling multiple requests

What about having a class being responsible for handling more than one request?

With MediatR

Imagine having 2 different requests:

record Ping : IRequest<string> { }
record Echo(string Message) : IRequest<string>;

Defining a handler able to handle both the types of request with MediatR is as simple as implementing both IRequestHandler<Ping, string> and IRequestHandler<Echo, string>:

class MyHandler :
    IRequestHandler<Ping, string>,
    IRequestHandler<Echo, string>
{
    public Task<string> Handle(Ping request, CancellationToken cancellationToken)
    {
        return Task.FromResult("Pong");
    }

    public Task<string> Handle(Echo request, CancellationToken cancellationToken)
    {
        return Task.FromResult(request.Message);
    }
}

code

Without MediatR

The plain OOP implementation is equally simple:

interface IMyHandler
{
    string Ping();
    string Echo(string message);
}

class MyHandler : IMyHandler
{
    string IMyHandler.Ping() => "Pong";
    string IMyHandler.Echo(string message) => message;
}

FAQs

How is the OOP approach preferrable?

Answer
Compare the interface of MyHandler with MediatR:

Task<string> Handle(Ping request, CancellationToken cancellationToken);
Task<string> Handle(Echo request, CancellationToken cancellationToken);

and without:

string Ping();
string Echo(string message);

The naming in the OOP interface is domain-driven; With MediatR the code tends to contain many repetitions of Send and Handle, which are a missed opportunity to use a business-driven, obiquitous language. The reference to domain notions is moved from the method name to the parameters. This once again how MediatR is basically a re-implementation of the native C# method dispatching.

It is also interesting to compare the 2 class types, and to notice how in one notions from the domain such as Ping and Echo mix with notions from the infrastructure, inherited from an external library:

class MyHandler :
    IRequestHandler<Ping, string>,
    IRequestHandler<Echo, string>

and how the other is instead purely domain-driven:

class MyHandler : 
	IMyHandler

Comments

GitHub Discussions