Design Patterns & Practices  

CQRS ≠ MediatR

When developers begin exploring scalable architecture patterns in .NET, two concepts often appear side by side: CQRS (Command Query Responsibility Segregation) and MediatR. It’s easy to assume they’re the same — or that one depends on the other. But let’s get this straight:

In this article, we’ll break down what CQRS truly means, how MediatR fits into the picture (if at all), and show real-world examples so you can apply the right concept at the right time.

What is CQRS?

CQRS (Command Query Responsibility Segregation) is a design pattern that separates read and write operations in your system.

In Simple Terms

  • Command: Changes the system state (Create, Update, Delete).

  • Query: Retrieves data (Read-only operations).

The idea is to decouple how you handle commands from how you handle queries, potentially allowing different models, teams, or even databases for each.

Example of CQRS (Without MediatR)

  
    // Command
public class CreateOrderCommand
{
    public string ProductId { get; set; }
    public int Quantity { get; set; }
}

// Command Handler
public class OrderCommandHandler
{
    public void Handle(CreateOrderCommand command)
    {
        // Validate and create order
    }
}

// Query
public class GetOrderByIdQuery
{
    public Guid OrderId { get; set; }
}

// Query Handler
public class OrderQueryHandler
{
    public OrderDto Handle(GetOrderByIdQuery query)
    {
        // Fetch and return order from DB
    }
}
  

Key Points

  • CQRS is about the separation of concerns, not about what library you use.

  • It can be implemented with or without MediatR.

What is MediatR?

MediatR is a simple .NET library by Jimmy Bogard that helps implement the mediator pattern. It allows sending messages (commands, queries, notifications) without directly referencing the handler.

In Simple Terms

  • Promotes in-process messaging.

  • Helps decouple sender and receiver.

Example of MediatR

  
    // Command
public class CreateOrderCommand : IRequest
{
    public string ProductId { get; set; }
    public int Quantity { get; set; }
}

// Command Handler
public class CreateOrderHandler : IRequestHandler<CreateOrderCommand>
{
    public Task Handle(CreateOrderCommand request, CancellationToken cancellationToken)
    {
        // Handle logic here
        return Task.CompletedTask;
    }
}

// Usage
await _mediator.Send(new CreateOrderCommand { ProductId = "P001", Quantity = 2 });
  

Why CQRS ≠ MediatR

While MediatR is commonly used in CQRS implementations, especially in .NET apps, it’s not a requirement.

You could

  • Use CQRS without MediatR by calling handlers directly.

  • Use MediatR in a system that doesn’t follow CQRS.

Think of MediatR as a tool in your CQRS toolbox — not the definition of it.

When to Use CQRS Without MediatR

Use CQRS alone when:

  • You want full control over dependencies.

  • You don’t want extra abstraction layers.

  • You are in a microservice or event-driven architecture.

Use CQRS with MediatR when:

  • You want clean separation and minimal ceremony.

  • You’re building a modular monolith or large application.

  • You favor testability and extensibility.

Summary

  • CQRS is a design principle to split reads and writes.

  • MediatR is a messaging library that simplifies communication between components.

  • They are not the same , but they can work well together .