Bilgisayar Genel

Clean Architecture’ta Pipeline Behavior Kullanımı

Tarafından yazılmıştır Halil Durmuş

Kurumsal .NET projelerinde kod tabanı büyüdükçe en büyük problem, iş kurallarının teknik detaylar arasında kaybolmasıdır. Özellikle CRM, ERP ve entegrasyon yoğun sistemlerde; validation, logging ve transaction gibi konular zamanla her handler’ın içine dağılır. Bu da hem okunabilirliği hem de sürdürülebilirliği ciddi şekilde zorlaştırır.

Clean Architecture bu noktada sadece katmanları ayırmakla kalmaz, sorumlulukları da net bir şekilde ayrıştırmayı hedefler. Command / Query ayrımı ve MediatR Pipeline Behavior’lar bu yaklaşımın pratikte en güçlü uygulamalarından biridir.

Command ve Query Ayrımı Neden Önemlidir?

Sistemde gerçekleştirilen her operasyonun bir niyeti vardır ve bu niyetin kod üzerinden açıkça okunabilmesi büyük önem taşır. Command’lar uygulamanın state’ini değiştirirken, Query’ler yalnızca veri okuma amacıyla çalışır. İlk bakışta basit görünen bu ayrım, proje büyüdükçe kodun anlaşılabilirliğini ve bakım kolaylığını ciddi ölçüde artırır.

Örneğin bir kullanıcı oluşturma işlemi ile kullanıcı detayı getirme işlemi aynı handler’da yer almamalıdır. Çünkü bu iki operasyonun sorumlulukları tamamen farklıdır.

C#
public record CreateUserCommand(string Name, string Email)
    : IRequest<Guid>;

public record GetUserByIdQuery(Guid Id)
    : IRequest<UserDto>;
C#

Bu yaklaşım sayesinde bir geliştirici sadece class adına bakarak bile ilgili operasyonun veri değiştirip değiştirmediğini anlayabilir.

MediatR ve Pipeline Behavior Mantığı

MediatR, Command ve Query’lerin tek bir merkezden yönetilmesini sağlar. Ancak asıl gücünü Pipeline Behavior yapısıyla gösterir. Pipeline Behavior’lar, handler çalışmadan önce ve sonra araya girerek ortak işlemleri merkezi bir noktadan yönetmemize olanak tanır.

Bu yapı sayesinde validation, logging veya transaction gibi tekrar eden kodları her handler’ın içine yazmak yerine, tek bir yerden kontrol edebiliriz. Böylece handler’lar yalnızca iş kuralına odaklanır.

Validation Pipeline ile Fail-Fast Yaklaşımı

Validation, çoğu projede handler içinde yapılan ve zamanla karmaşıklaşan bir süreçtir. Oysa validation, iş kuralı değil bir ön koşuldur. Bu nedenle handler’a hiç ulaşmadan kontrol edilmelidir.

FluentValidation ile oluşturulan bir Validation Pipeline, gelen request’i önce doğrular. Hata varsa işlem hiç başlamadan durdurulur.

C#
public class ValidationBehavior<TRequest, TResponse>
    : IPipelineBehavior<TRequest, TResponse>
{
    public async Task<TResponse> Handle(
        TRequest request,
        RequestHandlerDelegate<TResponse> next,
        CancellationToken cancellationToken)
    {
        // Validation işlemleri
        return await next();
    }
}
C#

Bu yaklaşımın en büyük faydası, sistemin fail-fast çalışması ve handler’ların gereksiz koddan arındırılmasıdır.

Logging Pipeline ile İzlenebilirlik

Kurumsal uygulamalarda bir işlemin ne zaman, hangi parametrelerle ve kim tarafından tetiklendiğini bilmek kritik öneme sahiptir. Logging Pipeline, her Command veya Query’nin giriş ve çıkış noktalarını merkezi olarak loglamamıza olanak tanır.

C#
_logger.LogInformation(
    "Handling {RequestName} with {@Request}",
    typeof(TRequest).Name,
    request);
C#

Bu sayede:

  • Handler’larda log tekrarı olmaz
  • Log formatı standartlaşır
  • Üretim ortamında hata ayıklamak kolaylaşır

Transaction Pipeline ile Tutarlı Veri Yönetimi

Transaction yönetimi, özellikle veri güncelleyen Command’lar için vazgeçilmezdir. Ancak bu işlemi her handler içinde yapmak, hem hata riskini artırır hem de kodu şişirir.

Transaction Pipeline, yalnızca Command’lar için transaction başlatır ve handler başarıyla tamamlandığında commit eder. Bir hata oluştuğunda ise rollback otomatik olarak devreye girer.

C#
await _dbContext.BeginTransactionAsync();
var response = await next();
await _dbContext.CommitAsync();
C#

Bu yapı sayesinde transaction yönetimi tek bir noktadan kontrol edilir ve tutarlılık sağlanır.

Pipeline Sırası Neden Kritik?

Pipeline Behavior’ların sırası, sistemin davranışını doğrudan etkiler. Genellikle önerilen sıra şu şekildedir:

  • Validation
  • Logging
  • Transaction
  • Handler

Bu sıralama sayesinde:

  • Hatalı request’ler transaction açılmadan elenir
  • Log’lar anlamlı ve tutarlı olur
  • Performans gereksiz yüklerden korunur

Gerçek Hayatta Ne Kazandırır?

Bu yaklaşım, özellikle uzun süre yaşayan ve sürekli evrilen projelerde büyük avantaj sağlar. Kod okunabilirliği artar, yeni geliştiricilerin projeye adapte olması kolaylaşır ve değişen iş kurallarına daha hızlı yanıt verilebilir.

Clean Architecture, CQRS ve Pipeline Behavior birlikte kullanıldığında, sistem sadece çalışan değil, aynı zamanda yaşayan ve büyüyebilen bir yapıya kavuşur.

Yazar hakkında

Halil Durmuş

1996 yılının Mart ayında Trabzon’da dünyaya geldim. Atatürk Üniversitesi, Bilgisayar Mühendisliği mezunuyum. Web sitemde ilgimi çeken konuları araştırarak yazılar paylaşıyorum.

Yorum Yap