Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Dependency'leri İçe Çevirmek: Layered Architecture Nerede Tıkanır?
Layered Architecture'da compile-time dependency yukarıdan aşağı aktığı için iş kuralları EF Core'a, SQLite'a ve dış API'lere kilitlenir; çözüm, runtime çağrı yönünü koruyup interface'leri onları kullanan domain project'ine taşıyarak referans okunu içe çevirmektir. Bookstore'da veritabanı olmadan test yazma ve kargo firmasını değiştirme senaryolarıyla, "interface ekledim, oldu" yanılgısı ve Hexagonal, Onion, Clean'in ortak fikri.
Hexagonal Architecture (Ports & Adapters): Uygulamayı Dış Dünyadan Yalıtmak
Hexagonal Architecture (Cockburn, 2005), uygulamayı UI, test, batch script ve veritabanından eşit uzaklıkta tutar: dış dünya amaca göre tanımlanmış port'lar üzerinden konuşur, her teknoloji bir adapter ile takılır. Bookstore'da IPlaceOrder driving port'unu Minimal API, console CSV import ve xUnit testiyle, IOrderStore driven port'unu EF Core ve in-memory adapter'la sürüyoruz; ASP.NET Core'un IServer'ı ve altıgenle ilgili yanlış okumalar.
Onion Architecture: Domain Model Merkezde, Altyapı Dış Halkada
Onion Architecture (Palermo, 2008) uygulamayı bağımsız bir domain model'in etrafına kurar: iç halkalar interface'leri tanımlar, dış halkalar implement eder, tüm coupling merkeze doğrudur ve çekirdek altyapıdan ayrı derlenip çalışabilir. Bookstore'un sipariş kodunu Domain Model, Domain Services ve Application Services halkalarına yerleştiriyor, layered ve Hexagonal'dan farkını, halka-project ilişkisini ve ASP.NET Core Identity örneğini gösteriyoruz.
Clean Architecture: Dependency Rule, Use Case'ler ve Sınırı Geçen Veri
Clean Architecture'ın (Martin, 2012) tek kuralı Dependency Rule'dur: kaynak kod dependency'leri yalnız içe bakar ve sınırı entity ya da veritabanı satırı değil, iç çemberin ihtiyacına göre sade bir veri yapısı geçer. Bookstore'da dört çemberin karşılıkları, EF Core satırını döndürmenin yarattığı JSON döngü hatası, output port ve presenter ile ASP.NET Core'daki Result döndüren pragmatik karşılığı ve Hexagonal, Onion, Clean karşılaştırması.
Application Layer ve Use Case'ler: MediatR Olmadan Handler, Validation ve Transaction Sınırı
Application layer'da her use case tek amaçlı bir handler class'ıdır: input validation Web'de, iş kuralı Domain'de kalır, beklenen hatalar Result ile döner ve tek bir SaveChanges transaction sınırını çizer. Scrutor ile decorator'larla cross-cutting işleri MediatR'sız eklemek ve MediatR'ın 13.0.0 sonrası lisans durumu.
Persistence Ignorance ve Infrastructure Adapter'ları: EF Core, HttpClient ve Dış Servisler
Persistence ignorance, domain class'larının hangi veritabanına ve ORM'e yazıldığından habersiz kalmasıdır; EF Core'da mapping'i IEntityTypeConfiguration ile Infrastructure'da tutarsın, ama constructor binding ve getter-only property'ler gibi kurallar domain'in şeklini yine de etkiler. Kargo firmasının API'sini typed HttpClient ile bir driven adapter'a sarmak, dış modeli içeri sızdırmamak ve generic repository ile IQueryable tuzağı.
Clean Architecture'ı Test Etmek ve Korumak: Core Test'leri, Adapter Test'leri ve Architecture Test'leri
Clean Architecture'da core'u in-memory adapter'larla veritabanı olmadan, adapter'ları Testcontainers ile üretimdeki SQL Server'a karşı test edersin; Dependency Rule'u ise ArchUnitNET kurallarıyla CI'da kırılmaz hale getirirsin. SQLite'ın gizlediği decimal hassasiyeti sorunu, derleyicinin yakalamadığı ihlaller, Types(true) olmadan hiçbir şey seçmeyen kural tuzağı ve NetArchTest'in 2021'den beri güncellenmediği notu.
Clean Architecture Ne Zaman Fazla Gelir? Template Kültü, Interface Patlaması ve Pragmatik Yol
Clean Architecture, korunacak iş kuralı olmayan CRUD ağırlıklı, kısa ömürlü ya da tek adapter'lı küçük servislerde fazla gelir; uzun ömürlü, kurallı ve çok adapter'lı bölgelerde ise karşılığını verir. Template kültü ve interface patlamasının belirtileri, aynı Dependency Rule'u tek project ve ArchUnitNET test'leriyle korumak, ve layered bir projeden FreezingArchRule ile kademeli geçiş.