Implementarea bazelor CQRS în .NET
După ce am înțeles conceptele de bază și structura recomandată, e timpul să trecem la implementare. În această etapă, vom configura MediatR și vom crea primele comenzi și interogări (queries) într-o aplicație .NET, folosind un exemplu simplu: Post.
3️⃣ Instalarea MediatR
Pentru a separa responsabilitățile și a evita legături directe între layere, folosim MediatR – o bibliotecă care facilitează trimiterea comenzilor și interogărilor către handler-ele dedicate.
🛠️ Instalare
În proiectul MyApp.Application, adaugă MediatR:
dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection
În MyApp.API (sau proiectul de UI/API), configurează serviciile în Program.cs:
builder.Services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssembly(typeof(MyApp.Application.AssemblyReference).Assembly));
Adaugă o clasă de referință în MyApp.Application:
namespace MyApp.Application;
public static class AssemblyReference { }
4️⃣ Crearea unei comenzi simple: CreatePostCommand
🧾 Command: CreatePostCommand.cs
using MediatR;
public record CreatePostCommand(string Title, string Content) : IRequest<Guid>;
IRequest<Guid> înseamnă că această comandă va returna un Guid (ID-ul postării create)
🧠 Handler: CreatePostCommandHandler.cs
5️⃣ Separarea completă pentru o interogare: GetPostByIdQuery
🔍 Query: GetPostByIdQuery.cs
PostDto este un obiect doar pentru afișare – fără logică de business.
🔄 Handler: GetPostByIdQueryHandler.cs
📦 PostDto.cs (în Application)
6️⃣ Rezumat: IRequest și IRequest
Tip de request |
Interfață |
Returnează |
---|---|---|
Command (scriere) |
IRequest<Unit> |
Nimic (Unit.Value) |
Command cu rezultat |
IRequest<Guid> |
De exemplu: ID-ul creat |
Query (citire) |
IRequest<PostDto> |
Un rezultat de tip DTO |
🧪 Exemplu de folosire din Controller / UI
🧠 Concluzie
În această etapă am implementat primele piese esențiale ale unui sistem CQRS:
-
✅ Comenzi care modifică starea aplicației
-
✅ Interogări separate pentru citire
-
✅ Handler-e dedicate și independente
-
✅ MediatR ca intermediar central
🏁 Ce urmează
În următorul articol vom adăuga:
-
✅ Validări cu FluentValidation
-
✅ Mapping între DTO-uri și entități
-
✅ Separarea clară între WriteModel și ReadModel