CQRS with MediatR
Implementing Mediator pattern using ASP.NET Core 5.0
In my previous article, we have discussed the usability of CQRS pattern, pros and cons as well as its implementation using ASP.NET Core 5.0.
In case if you haven’t read it yet.
If you had noticed, the main issue was using CQRS was the constructor overloading. The more the controller gets complexed more the constructor gets cluttered with command and query handlers hence,difficult to maintain.
As a solution for this MediatR pattern is introduced and there will be a single entry point and MediatR is responsible for resolving the respective command and query handlers.
MediatR
MediatR is a library developed by Jimmy Bogard and that can be used to implement mediator pattern.
Mediator pattern
Is a behavioral pattern which defines an object that encapsulates how a set of objects interact.
Pros
- Decoupled components — A class depends only on the mediator. It removes the dependency between different components/classes so the communication among classes are encapsulated within mediator.
- Separation of concern — As the mediator implements an abstract level of implementation for command and queries, each handler has its own level of execution context.
Cons
- Complexity — Due to the heaviness of the mediator implementation, this could easily make complex for anyone without having a proper understanding.
For the sake of simplicity of the entity creation, schema changes and project initialization will not be discussed here which is the same as the previous post. Let’s focus only on the MediatR implementation.
First, we will install NuGet packages for MediatR via package manager console or NuGet package manager.
Install-Package MediatR Install-Package MediatR.Extensions.Microsoft.DependencyInjection
Then register the MediatR service in Startup.cs
Next, inject the IMediatR interface to the Customer controller.
Controllers>CustomerController.cs
Let’s modify SaveCustomerRequestModel to implement IRequest interface.
RequestModels>CommandRequests>SaveCustomerRequestModel.cs
Note that all the request models should implement IRequest<T> where the T should be the type of the response model.
In MediatR void does not consider as a valid return type for C#. Instead using void it has the type of Unit.
In our implementation, Response model was left empty so that the request will be marked as void.
Now let’s see how we implement the SaveCustomerRequestModel in the SaveCustomerCommandHandler.
Handlers>CommandHandlers>SaveCustomerCommandHandler.cs
Important to note
- Command handler was implemented with IRequestHandler.
- IRequestHandler has the parameters as <TRequest,TResponse>
- TRequest — SaveCustomerRequestModel
- TResponse — Unit (void)
- Every Handler implementation must have a return type.
- Separate handler interface is not required as IReqeustHandler provides its own implementation.
Controllers>CustomerController.cs
Note that the constructor of the Customer Controller is injected only IMeadiatR and that can be used with multiple request handlers without having to overload it.
The beauty of the MediatR is, when the Send method is called, based on the type of the request, it resolves and redirect the request to the appropriate handler.
So when the above save-customer is invoked using postman.
Finally, we will see how to implement get-all endpoint using MediatR.
As we discussed earlier, every command/query must have a request model. But first, let’s implement our response model and this is exactly same as the previous post.
ResponseModels>QueryResponses>AllCustomerQueryResponseModel.cs
Then the AllCustomerQueryRequestModel
RequestModels>QueryRequests>AllCustomerQueryRequestModel.cs
Note that List<AllCustomerQueryResponseModel> has been set as the type of the response.
Next the implementing query handler.
Handlers>QueryHandlers>AllCustomerQueryHandler.cs
Note that how the request model and response type have been set as the parameters for IRequestHandler.
As the last step we will modify our get-all endpoint in the Customer controller.
Note that no changes is made to the constructor and the query request model is passed as a parameter.
So when the above method is executed
For the implementation of customer-id end point download the source code along with all the project changes.
If you enjoyed the post leave a clap or a comment.
Happy Coding!!!!
Source code : https://github.com/lakshithacodes/CQRSwithMediatR
Reference