Skip to main content

Overview

The Intent.Application.MediatR module implements the CQRS (Command Query Responsibility Segregation) design pattern using the MediatR library. It generates commands, queries, and their corresponding handlers based on your service models.
This module is part of the CQRS paradigm. If you prefer a traditional service-based approach, consider using the Intent.Application.ServiceImplementations module instead.

What Gets Generated

When you model commands and queries in the Services Designer, this module generates:
  • Command Classes - IRequest<TResponse> implementations representing write operations
  • Command Handlers - IRequestHandler<TRequest, TResponse> implementations processing commands
  • Query Classes - IRequest<TResponse> implementations representing read operations
  • Query Handlers - IRequestHandler<TRequest, TResponse> implementations processing queries
  • ICommand Interface - Marker interface for identifying commands
  • IQuery Interface - Marker interface for identifying queries

CQRS Pattern Benefits

The CQRS paradigm provides:
  • Separation of Concerns - Read and write operations are optimized independently
  • Use Case-Centric - Each operation is a discrete request/response object
  • Pipeline Behaviors - Add validation, logging, transactions as cross-cutting concerns
  • Loose Coupling - Mediator pattern decouples callers from handlers
  • Scalability - Read and write models can scale independently

When to Use CQRS

  • Operations benefit from specialized pipeline behaviors
  • Strict separation between commands and queries
  • Individual operations have complex concerns
  • Loose coupling via mediator pattern

When to Use Traditional Services

  • Unified domain model and service structure
  • Operations grouped by business capability
  • Class-based approach with methods
  • Team familiar with traditional patterns

Generated Code Examples

Command Example

Given a “Create Customer” command modeled in the Services Designer:
CreateCustomerCommand.cs
public class CreateCustomerCommand : IRequest<Guid>, ICommand
{
    public CreateCustomerCommand(string name, string surname, string email)
    {
        Name = name;
        Surname = surname;
        Email = email;
    }

    public string Name { get; set; }
    public string Surname { get; set; }
    public string Email { get; set; }
}

Command Handler Example

CreateCustomerCommandHandler.cs
[IntentManaged(Mode.Merge, Signature = Mode.Fully)]
public class CreateCustomerCommandHandler : IRequestHandler<CreateCustomerCommand, Guid>
{
    [IntentManaged(Mode.Merge)]
    public CreateCustomerCommandHandler()
    {
    }

    [IntentManaged(Mode.Fully, Body = Mode.Merge)]
    public async Task<Guid> Handle(CreateCustomerCommand request, CancellationToken cancellationToken)
    {
        // IntentInitialGen
        // TODO: Implement Handle (CreateCustomerCommandHandler) functionality
        throw new NotImplementedException("Your implementation here...");
    }
}

Query Example

GetCustomerByIdQuery.cs
public class GetCustomerByIdQuery : IRequest<CustomerDto>, IQuery
{
    public GetCustomerByIdQuery(Guid id)
    {
        Id = id;
    }

    public Guid Id { get; set; }
}

Query Handler Example

GetCustomerByIdQueryHandler.cs
[IntentManaged(Mode.Merge, Signature = Mode.Fully)]
public class GetCustomerByIdQueryHandler : IRequestHandler<GetCustomerByIdQuery, CustomerDto>
{
    [IntentManaged(Mode.Merge)]
    public GetCustomerByIdQueryHandler()
    {
    }

    [IntentManaged(Mode.Fully, Body = Mode.Merge)]
    public async Task<CustomerDto> Handle(GetCustomerByIdQuery request, CancellationToken cancellationToken)
    {
        // IntentInitialGen
        // TODO: Implement Handle (GetCustomerByIdQueryHandler) functionality
        throw new NotImplementedException("Your implementation here...");
    }
}

Configuration

Consolidate Command/Query Associated Files

CQRS Settings.Consolidate Command/Query associated files into single file
boolean
default:"false"
When enabled, commands/queries and their handlers are generated in a single file instead of separate files in sub-folders.Disabled (default):
Commands/
  CreateCustomer/
    CreateCustomerCommand.cs
    CreateCustomerCommandHandler.cs
    CreateCustomerCommandValidator.cs
Enabled:
Commands/
  CreateCustomerCommand.cs  // Contains command, handler, and validator

Property Default Values

Command and query properties can have default values in the Services Designer. Default values are applied in the constructor only if no subsequent properties lack default values. Incorrect ordering (default value ignored):
// Name has a default but surname/email after it don't
public CreateCustomerCommand(string? name, string surname, string email)
{
    Name = name;  // Default not applied
    Surname = surname;
    Email = email;
}
Correct ordering (default value applied):
// Name moved after required parameters
public CreateCustomerCommand(string surname, string email, string? name = "John")
{
    Surname = surname;
    Email = email;
    Name = name;  // Default applied!
}
The Services Designer will warn you if properties with default values are incorrectly ordered.

MediatR License Options

Starting with MediatR v13.0, a commercial license is required. Prior versions remain free.
Use Pre-Commercial Version
boolean
default:"false"
Controls which version of MediatR is used:
  • Enabled: Locks to the last free version (pre-v13)
  • Disabled: Uses the latest commercial edition (requires license key)

Configuring Your License Key

If using the commercial version, configure your license key: Option 1: appsettings.json
{
  "MediatR": {
    "LicenseKey": "your-license-key-here"
  }
}
Option 2: Environment Variable
MediatR__LicenseKey=your-license-key-here

Get a License Key

Learn how to obtain a MediatR commercial license

Dependencies

This module requires:
  • Intent.Application.DependencyInjection.MediatR - Registers MediatR services
  • Intent.Common.CSharp - C# code generation utilities
  • Intent.Modelers.Services.CQRS - CQRS modeling designer

MediatR Behaviours

Add cross-cutting concerns like logging, validation, and transactions

MediatR CRUD

Auto-generate CRUD operation implementations

MediatR FluentValidation

Add FluentValidation to your command/query pipeline

Additional Resources

Build docs developers (and LLMs) love