Introduction
In modern .NET development, building scalable, maintainable, and clean applications is a top priority. One of the most popular ways to achieve this is by following Clean Architecture principles. But as your application grows, managing communication between different layers can become messy.
This is where MediatR in .NET comes into play.
MediatR helps you implement the Mediator Design Pattern, which allows different parts of your application to communicate without directly depending on each other. This results in cleaner code, better separation of concerns, and easier testing.
In this article, we will understand how to use MediatR in .NET for clean architecture implementation in simple words, step by step, with practical examples.
What is MediatR in .NET?
MediatR is a lightweight library that helps you implement the Mediator pattern in .NET applications.
Simple Explanation
Instead of one class directly calling another class, MediatR acts like a middleman (mediator).
This removes tight coupling between components.
Why MediatR is Important for Clean Architecture
In Clean Architecture:
MediatR helps achieve this by:
Decoupling controllers from business logic
Moving logic into handlers
Making code more modular and testable
What is Clean Architecture in .NET?
Clean Architecture is a design approach where your application is divided into layers, each with a clear responsibility.
Common Layers
Presentation Layer → Controllers (API/UI)
Application Layer → Business logic (MediatR handlers)
Domain Layer → Core entities and rules
Infrastructure Layer → Database, external services
Key Idea
Dependencies should always point inward, not outward.
This keeps your core logic safe and independent.
Installing MediatR in .NET Project
To use MediatR, you first need to install it.
Using NuGet Package Manager
dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection
Register MediatR in Program.cs
builder.Services.AddMediatR(typeof(Program));
Explanation
This tells .NET to scan your project and register all MediatR handlers automatically.
Core Concepts of MediatR
To understand how MediatR works, you need to know three main components.
1. Request (Command or Query)
A request represents an action.
Command → Changes data
Query → Reads data
public record GetUserQuery(int Id) : IRequest<string>;
2. Handler
A handler processes the request.
public class GetUserHandler : IRequestHandler<GetUserQuery, string>
{
public Task<string> Handle(GetUserQuery request, CancellationToken cancellationToken)
{
return Task.FromResult($"User Id: {request.Id}");
}
}
3. Mediator (IMediator)
This is the main interface used to send requests.
private readonly IMediator _mediator;
public UserController(IMediator mediator)
{
_mediator = mediator;
}
How MediatR Works Step-by-Step
A request is created
The request is sent using IMediator
MediatR finds the correct handler
The handler executes logic
Response is returned
This flow keeps everything clean and organized.
Using MediatR in Clean Architecture
Let’s understand with a real-world example.
Step 1: Create Query
public record GetProductQuery(int Id) : IRequest<string>;
Step 2: Create Handler
public class GetProductHandler : IRequestHandler<GetProductQuery, string>
{
public Task<string> Handle(GetProductQuery request, CancellationToken cancellationToken)
{
return Task.FromResult($"Product Id: {request.Id}");
}
}
Step 3: Use in Controller
[ApiController]
[Route("api/products")]
public class ProductController : ControllerBase
{
private readonly IMediator _mediator;
public ProductController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
var result = await _mediator.Send(new GetProductQuery(id));
return Ok(result);
}
}
Explanation
The controller does not know anything about business logic. It simply sends a request using MediatR.
This makes your API clean and easy to manage.
Benefits of Using MediatR in .NET
1. Loose Coupling
Components do not depend on each other directly.
2. Clean Code Structure
Each feature is separated into its own request and handler.
3. Easy Testing
You can test handlers independently without controllers.
4. Better Maintainability
Code becomes easier to update and scale.
5. Supports CQRS Pattern
You can easily separate read and write operations.
MediatR with CQRS (Command Query Responsibility Segregation)
MediatR works perfectly with CQRS.
Command Example
public record CreateOrderCommand(string ProductName) : IRequest<bool>;
Query Example
public record GetOrderQuery(int Id) : IRequest<string>;
Why This Matters
Best Practices for Using MediatR in .NET
Keep handlers small and focused
Use one handler per request
Avoid putting too much logic in controllers
Organize code by feature (feature folders)
Use pipeline behaviors for logging and validation
Common Mistakes to Avoid
Overusing MediatR for simple logic
Creating very large handlers
Mixing business logic in controllers
Not following proper folder structure
When to Use MediatR
Use MediatR when:
You are building enterprise applications
You want clean architecture in .NET
Your project is growing and becoming complex
Avoid it in very small projects where it may add unnecessary complexity.
Summary
Using MediatR in .NET for clean architecture implementation helps you build applications that are clean, scalable, and easy to maintain. It acts as a mediator between different layers, reducing dependencies and improving code structure. By using requests and handlers, you can separate business logic from controllers, making your application more organized and testable. When combined with Clean Architecture and CQRS, MediatR becomes a powerful tool for modern .NET development.