Overview
CQRS separates the responsibility of handling commands that change state from queries that read state. This separation provides several benefits:- Clarity: Commands and queries have distinct interfaces and purposes
- Scalability: Read and write operations can be optimized independently
- Security: Different authorization rules can apply to commands vs queries
- Testing: Easier to test and mock handlers
Command Interfaces
ICommand
TheICommand interface represents a command that doesn’t return a value (returns Unit).
BuildingBlocks/CQRS/ICommand.cs
ICommandHandler
TheICommandHandler interface defines handlers that process commands.
BuildingBlocks/CQRS/ICommandHandler.cs
Query Interfaces
IQuery
TheIQuery interface represents a query that returns data.
BuildingBlocks/CQRS/IQuery.cs
IQueryHandler
TheIQueryHandler interface defines handlers that process queries.
BuildingBlocks/CQRS/IQueryHandler.cs
Registration
Register MediatR and all handlers in your service’s DependencyInjection.cs:Usage in Controllers
InjectIMediator and send commands or queries:
Best Practices
Use Records for Commands and Queries
Use Records for Commands and Queries
Records provide immutability and value-based equality, making them ideal for commands and queries.
Keep Handlers Focused
Keep Handlers Focused
Each handler should have a single responsibility. Don’t add multiple operations to one handler.
Queries Should Not Modify State
Queries Should Not Modify State
Queries should be read-only operations. Use
AsNoTracking() with Entity Framework.Commands Should Return Minimal Data
Commands Should Return Minimal Data
Commands should return only essential data (like ID), not full entities.
Related Topics
Validation Behavior
Automatically validate commands before execution
Exception Handling
Handle errors in command and query handlers
