MediatR ve CQRS¶
MediatR ve CQRS (Command Query Responsibility Segregation) pattern’ı, modern .NET uygulamalarında yaygın olarak kullanılan güçlü bir mimari yaklaşımdır. Bu rehber, bu pattern’ların etkili kullanımına dair ipuçları ve best practice’leri içermektedir.
İçindekiler¶
- Temel Kavramlar
- Command Pattern
- Query Pattern
- Pipeline Behaviors
- Event Handling
- Validation
- Error Handling
- Testing
- Best Practices
Her bölüm, konunun detaylı bir şekilde anlatımını ve pratik örneklerini içermektedir.
Temel Kavramlar¶
MediatR Nedir?¶
MediatR, in-process mesajlaşma için basit bir mediator pattern implementasyonudur. Request/response ve notification pattern’larını destekler.
CQRS Nedir?¶
CQRS, veri okuma (Query) ve yazma (Command) işlemlerini birbirinden ayıran bir pattern’dır. Bu ayrım, uygulamanın ölçeklenebilirliğini ve bakımını kolaylaştırır.
Pratik İpuçları¶
1. Command ve Query Ayrımı¶
// Command örneği
public class CreateProductCommand : IRequest<int>
{
public string Name { get; set; }
public decimal Price { get; set; }
}
// Query örneği
public class GetProductByIdQuery : IRequest<ProductDto>
{
public int Id { get; set; }
}
2. Pipeline Behavior Kullanımı¶
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
// Request öncesi loglama
var response = await next();
// Response sonrası loglama
return response;
}
}
3. Event Handling¶
public class ProductCreatedEvent : INotification
{
public int ProductId { get; set; }
}
public class ProductCreatedEventHandler : INotificationHandler<ProductCreatedEvent>
{
public async Task Handle(ProductCreatedEvent notification, CancellationToken cancellationToken)
{
// Event handling logic
}
}
Best Practices¶
-
Command ve Query Sınıfları - Command’lar immutable olmalı - Query’ler sadece veri okumalı - Her command/query tek bir iş yapmalı
-
Handler Organizasyonu - Her handler tek bir sorumluluğa sahip olmalı - Business logic handler içinde olmalı - Cross-cutting concern’ler behavior’lara taşınmalı
-
Validation - FluentValidation kullanımı önerilir - Validation logic’i behavior’larda olmalı
-
Error Handling - Global exception handling kullanılmalı - Özel exception tipleri tanımlanmalı
Örnek Proje Yapısı¶
Project/
├── Commands/
│ ├── CreateProduct/
│ │ ├── CreateProductCommand.cs
│ │ ├── CreateProductCommandHandler.cs
│ │ └── CreateProductCommandValidator.cs
│ └── UpdateProduct/
├── Queries/
│ ├── GetProductById/
│ │ ├── GetProductByIdQuery.cs
│ │ └── GetProductByIdQueryHandler.cs
│ └── GetProducts/
├── Events/
│ ├── ProductCreated/
│ │ ├── ProductCreatedEvent.cs
│ │ └── ProductCreatedEventHandler.cs
│ └── ProductUpdated/
└── Behaviors/
├── LoggingBehavior.cs
└── ValidationBehavior.cs