This is an appendix of You probably don’t need MediatR: it offers practical guidance to implement the MediatR’s functionalities using a plain object-oriented approach.
It goes through all the examples in the MediatR readme file and all the snippets in the ‘samples’ project: for each of them, it provides an implementation based on OOP standard patterns, together with some design considerations.
All the code mentioned hereinafter is available in the without-mediatr repository.
interface IMyHandler
{
string Echo(string message, int whatever);
}
class MyHandler : IMyHandler
{
string IMyHandler.Echo(string message, int whatever) => "do work";
}
Other functionalities such as notifications and pipelines are easily implemented with the Composite Pattern.
surprising pattern it might seem, this is really all that’s necessary.
Not only does this cover all of the MediatR functionalities, but also some that are not possible with MediatR, such as pipelines for notifications, handling of multiple requests and sending requests to multiple handlers.
A plain OOP approach typically demonstrates better design qualities compared to one built with MediatR.
Question: Isn’t this building MediatR by hand?
Answer: Not at all. Instead of implementing IRequestHandler<Message>
, let the handler implement your own IYourInterface
. It’s that simple.
Question: What’s the benefit?
Answer: Have a look to each use case: you will find a bit of comments at the bottom.
Question: What if I’m into Functional Programming?
Answer: Even better! You will benefit even more from this approach. As per its author’s acknowledgment, “MediatR is intentionally class/object-oriented, it’s likely not a good fit in a functional-style application”, would “get replaced by proper functional language features” and it would not be necessary in F#.
Relying on pure C# will pave the way for you to work with function composition, Reactive Extensions, language-ext and the like.