Skip to content

Mediator Pattern in ASP .Net Core 3.1

The mediator pattern is a behavioral design pattern that helps to reduce chaotic dependencies between objects. The main goal is to disallow direct communication between the objects and instead force them to communicate only via the mediator.

Problem

Services or classes often have several dependencies on other classes and quickly you end up with a big chaos of dependencies. The mediator pattern serves as an organizer and calls all needed services. No service has a dependency on another one, only on the mediator.

You can see the mediator pattern also in real life. Think about a big airport like JFK with many of arriving and departing planes. They all need to be coordinated to avoid crashes. It would be impossible for a plan to talk to all other planes. Instead, they call the tower, their mediator, and the tower talks to all planes and organizes who goes where.

Advantages and Disadvantages of the Mediator Pattern

The mediator pattern brings a couple of advantages:

  • Less coupling: Since the classes don’t have dependencies on each other, they are less coupled.
  • Easier reuse: Fewer dependencies also helps to reuse classes.
  • Single Responsibility Principle: The services don’t have any logic to call other services, therefore they only do one thing.
  • Open/closed principle: Adding new mediators can be done without changing the existing code.

There is also one big disadvantage of the mediator pattern:

  • The mediator can become such a crucial factor in your application that it is called a “god class”.

Implementation of the Mediator Pattern

You can find the code of  the finished demo on GitHub.

In my microservices, the controllers call all needed services and therefore work as the mediator. Additionally, I am using the MediatR NuGet package, which helps to call the services.

Installing MediatR

I am installing the MediatR and the MediatR.Extensions.Microsoft.DependencyInjection in my Api project. In the Startup class, I registered my mediators using services.AddMediatR(Assembly.GetExecutingAssembly()); I can do this because the controllers are in the same project. In the OrderApi, I am also using the ICustomerNameUpdateService interface as mediator. Therefore, I also have to register it.

Register the mediators from the same assembly and from another one to use the mediator pattern
Register the mediators from the same assembly and from another one

Now, I can use the IMediator object with dependency injection in my controllers.

Inject the IMediator in the controller to use the mediator pattern
Inject the IMediator in the controller

Using the Mediator pattern

Every call consists of a request and a handler. The request is sent to the handler which processes this request. A request could be a new object which should be saved in the database or an id of on object which should be retrieved. I am using CQRS, therefore my requests are either a query for read operations or a command for a write operation.

In the OrderController, I have the Order method which will create a new Order object. To create the Order, I create a CreateOrderCommand and map the Order from the post request to the Order of the CreateOrderCommandObject. Then I use the Send method of the mediator.

Create a new Order by sending a CreateOrderCommand
Create a new Order by sending a CreateOrderCommand

The request (or query and command in my case) inherit from IRequest<T> interface which where T indicates the return value. If you don’t have a return value, then inherit from IRequest.

Implementation of the CreateOrderCommand
Implementation of the CreateOrderCommand

The send method sends the object to the CreateOrderCommmandHandler. The handler inherits from IRequestHandler<TRequest, TResponse> and implements a Handle method. This Handle method processes the CreateOrderCommand. In this case, it calls the AddAsync method of the repository and parses the Order.

The Handler processes the request
The Handler processes the request

If you don’t have a return value, the handler inherits from IRequestHandler<TRequest>.

Conclusion

The mediator pattern is a great pattern to reduce the dependencies within your application which helps you to reuse your components and also to keep the Single Responsible Principle. I showed I implemented it in my ASP .net core 3.1 microservices using the MediatR NuGet package.

You can find the code of  the finished demo on GitHub.

In my next post, I will implement RabbitMQ which enables my microservices to exchange data in a decoupled asynchronous way.

Published inASP.NET MVC / CoreDesign PatternProgramming

Be First to Comment

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    RSS
    Follow by Email
    LinkedIn
    Share