Overview
CQRS (Command Query Responsibility Segregation) is a pattern that separates read and write operations into distinct models. Intent Architect implements CQRS using the MediatR library through theIntent.Application.MediatR module, generating all the necessary infrastructure for commands, queries, and their handlers.
Core Principle
Commands change state and don’t return data. Queries return data and don’t change state. This separation enables independent optimization, scaling, and reasoning about each operation type.
Why Use CQRS?
Separation of Concerns
Read and write models can be optimized independently for their specific purposes
Scalability
Scale read and write operations separately based on actual load patterns
Pipeline Behaviors
Apply cross-cutting concerns like validation, logging, and transactions per operation type
Loose Coupling
Mediator pattern reduces direct dependencies between components
Commands
Commands represent intentions to change the application’s state. They encapsulate all the information needed to perform an action.Command Structure
Command Characteristics
- Intent to Change State: Commands express what should happen
- Return Minimal Data: Typically return only an ID or success indicator
- Validation: Can be validated using FluentValidation before execution
- Side Effects: Commands modify data, trigger events, or perform actions
Commands that don’t return a value implement
IRequest (from MediatR). Commands that return a value implement IRequest<TResponse>.Queries
Queries retrieve data without modifying state. They are optimized for reading and can return complex result sets.Query Structure
Query Characteristics
- No State Changes: Queries are read-only operations
- Return Data: Always return DTOs or view models
- Optimized for Reading: Can use projections, includes, and database views
- Idempotent: Calling the same query multiple times produces the same result
Modeling CQRS in Intent Architect
Commands and Queries are modeled in the Services Designer using the CQRS paradigm:Create a Service Package
In the Services Designer, create or select a service package where your operations will be defined.
Add Commands
Create Command elements representing state-changing operations:
- Right-click → New Command
- Define properties for the command data
- Specify return type (optional, typically Guid or void)
Add Queries
Create Query elements representing data retrieval operations:
- Right-click → New Query
- Define query parameters as properties
- Specify return type (DTO or collection of DTOs)

Generated Artifacts
TheIntent.Application.MediatR module generates the following artifacts:
Core Interfaces
File Organization
Intent Architect provides flexible file organization through settings:- Separate Files (Default)
- Consolidated Files
Each command/query has its own folder with handler and validator alongside:
Configure file consolidation in Application Settings → CQRS Settings → “Consolidate Command/Query associated files into single file”
MediatR Pipeline Behaviors
One of CQRS’s key benefits is the ability to apply cross-cutting concerns through MediatR pipeline behaviors.Validation Behavior
Transaction Behavior
Integration with API Layer
Commands and queries integrate seamlessly with ASP.NET Core controllers:The
Intent.AspNetCore.Controllers.Dispatch.MediatR module automatically generates controllers that dispatch to MediatR handlers.CQRS vs Traditional Services
- CQRS Paradigm
- Traditional Services
When to Use:
- Operations have distinct read/write optimization needs
- You want pipeline behaviors (validation, logging, transactions)
- Loose coupling via mediator pattern is important
- Individual operations have complex, unique concerns
Intent.Application.MediatRStructure:Advanced Scenarios
CRUD Operations
TheIntent.Application.MediatR.CRUD module generates complete CRUD operations:
Property Default Values
Commands support default parameter values in constructors:MediatR Licensing
Starting with MediatR v13.0, a commercial license is required. Configure this in your application settings:- Pre-Commercial (Free)
- Commercial License
Enable “Use Pre-Commercial Version” setting to use MediatR v12.x (the last free version):
License keys can be obtained from Jimmy Bogard’s announcement.
Testing CQRS Operations
Unit Testing Handlers
Integration Testing
Related Modules
FluentValidation
Intent.Application.MediatR.FluentValidation - Automatic validation for commands and queriesCRUD Generation
Intent.Application.MediatR.CRUD - Auto-generate common CRUD operationsBehaviors
Intent.Application.MediatR.Behaviours - Pre-built pipeline behaviorsBest Practices
Keep Commands and Queries Focused
Keep Commands and Queries Focused
Each command or query should do one thing:
- Single Responsibility Principle applies
- Easier to test and maintain
- Clearer intent and naming
Validate Commands, Not Queries
Validate Commands, Not Queries
Commands change state and should be validated:
- Use FluentValidation for command validation
- Queries typically don’t need validation
- Invalid query parameters can return empty results or 404
Use DTOs for Query Results
Use DTOs for Query Results
Never return domain entities from queries:
- Map to DTOs using AutoMapper or Mapperly
- DTOs can be optimized for specific views
- Protects domain model from API changes
Leverage Pipeline Behaviors
Leverage Pipeline Behaviors
Apply cross-cutting concerns via behaviors:
- Validation before execution
- Logging and performance monitoring
- Transaction management
- Authorization checks
