Backend & Yazılım Mimarisi 5 dk okuma

ASP.NET Core Projelerinde Katmanlı Mimari: Ne Zaman Fayda Sağlar, Ne Zaman Gereksizdir?

5 dk okuma

Giriş

Katmanlı mimari, .NET projelerinde en çok konuşulan ama en kolay yanlış uygulanan konulardan biri. Bir solution içinde dört veya beş proje açmak tek başına mimari kalite sağlamıyor. Asıl mesele, hangi kodun nerede yaşayacağını ve hangi katmanın hangi katmana bağımlı olacağını netleştirmek.

ASP.NET Core katmanlı mimari yaklaşımını doğru kullandığımızda iş kuralları veri tabanından, kullanıcı arayüzünden ve üçüncü parti servislerden daha bağımsız hale geliyor. Bunun sonucu olarak kodun test edilmesi kolaylaşıyor, değişikliklerin etkisi daralıyor ve proje büyüdüğünde ekip içinde sorumluluklar daha anlaşılır oluyor.

Ancak küçük bir uygulamada gereksiz katmanlar açmak da ters etki yaratabilir. Bu yüzden mimariyi bir şablon gibi değil, projenin karmaşıklığına göre uygulanması gereken bir araç olarak görmek daha sağlıklı.

Katmanlı mimari aslında neyi çözer?

Bir web uygulamasında aynı anda birçok sorumluluk bulunur: HTTP isteğini almak, iş kuralını çalıştırmak, veri tabanına erişmek, e-posta göndermek, dosya kaydetmek veya harici bir API’ye çağrı yapmak. Bu görevlerin tamamını controller veya service sınıflarında toplamak ilk başta hızlı görünür, fakat proje büyüdükçe kodun nereden nereye bağlı olduğunu takip etmek zorlaşır.

Katmanlı mimarinin temel amacı sorumlulukları ayırmaktır. Kullanıcı arayüzü iş kuralının ayrıntısını bilmez; iş kuralı SQL Server’ın nasıl çalıştığını bilmek zorunda değildir; altyapı servisleri ise uygulamanın merkezindeki kuralları uygulayan parçalar olarak konumlanır. Microsoft’un Clean Architecture anlatımında da iş mantığının merkezde tutulması ve altyapı detaylarının bu merkeze bağımlı olması vurgulanıyor.

Hangi katmanlar gerçekten gerekli?

Orta ve büyük ölçekli bir ASP.NET Core uygulamasında Domain, Application, Infrastructure ve Web ayrımı çoğu zaman yeterli bir başlangıçtır.

Domain katmanı temel varlıkları ve iş açısından anlamlı kuralları içerir. Application katmanı kullanım senaryolarını, servis arayüzlerini ve uygulama akışını koordine eder. Infrastructure; Entity Framework Core, dosya sistemi, e-posta ve dış servis istemcileri gibi teknik detayları uygular. Web katmanı ise MVC, Razor Pages veya Web API üzerinden dış dünyayla iletişim kurar.

Bu ayrım her projede birebir aynı olmak zorunda değil. Bazen Domain ve Application tek proje içinde kalabilir. Önemli olan klasör ve proje sayısı değil, bağımlılıkların kontrol altında olmasıdır.

Dependency Injection neden önemli?

ASP.NET Core’un yerleşik dependency injection desteği katmanlı mimariyi uygulanabilir hale getiren en önemli özelliklerden biri. Application katmanında bir IEmailSender veya IProductRepository arayüzü tanımlayıp gerçek implementasyonu Infrastructure tarafında oluşturabilirsiniz.

Böylece iş mantığı doğrudan SMTP, SQL Server veya başka bir kütüphaneye bağlanmaz. Test sırasında gerçek servisin yerine sahte bir implementasyon verilebilir. Aynı zamanda teknoloji değişikliğinde iş kurallarını yeniden yazmak gerekmez.

Burada dikkat edilmesi gereken nokta her sınıf için gereksiz bir interface üretmemek. Soyutlama, gerçekten değişebilecek veya test sırasında ayrıştırılması gereken bağımlılıklarda anlamlıdır.

Ne zaman aşırı mimariye dönüşür?

Bir projede iki ekran, birkaç tablo ve sınırlı iş kuralı varsa sekiz ayrı proje oluşturmak geliştirme hızını düşürebilir. Her işlem için command, handler, repository, manager ve adapter zinciri oluşturmak kodun anlaşılmasını kolaylaştırmak yerine zorlaştırabilir.

Mimaride en önemli soru ‘bu katmanı neden açıyorum?’ olmalı. Cevap yalnızca ‘Clean Architecture böyle diyor’ ise yeniden düşünmek gerekir. Gerçek bir bağımlılığı ayırıyor, test kolaylığı sağlıyor veya farklı ekiplerin sorumluluğunu netleştiriyorsa katman anlamlıdır.

İyi mimari mümkün olan en fazla soyutlama değil, ihtiyaç duyulan kadar soyutlamadır.

Pratik bir başlangıç yaklaşımı

Yeni bir ASP.NET Core projesinde önce domain kurallarını ve ana kullanım senaryolarını belirlemek iyi bir başlangıçtır. Ardından veri erişimi ve dış servis bağımlılıklarını ayrı tutun. Web katmanının doğrudan DbContext üzerinden iş kuralları yürütmesini engelleyin.

Servis sınırlarını belirlerken veri tabanı tablolarını değil iş süreçlerini düşünmek daha iyi sonuç verir. Örneğin OrderService yalnızca trOrderHeader benzeri bir tablonun CRUD servisi olmamalı; sipariş oluşturma, doğrulama veya durum değiştirme gibi anlamlı işlemleri temsil etmelidir.

Son olarak test edilebilirliği mimarinin doğal sonucu olarak değerlendirin. Domain ve Application katmanları altyapıdan bağımsızsa unit test yazmak çok daha kolay hale gelir.

Sonuç

ASP.NET Core katmanlı mimari, proje büyüdükçe ortaya çıkan bağımlılık ve bakım problemlerini azaltmak için güçlü bir yaklaşım. Fakat mimariyi proje sayısıyla ölçmek yerine bağımlılık yönü, sorumluluk ayrımı ve test edilebilirlik üzerinden değerlendirmek gerekir.

Küçük projelerde sade kalmak, büyük projelerde ise iş kurallarını merkeze alıp altyapıyı dışarı taşımak çoğu zaman en dengeli yaklaşımı verir. İyi tasarlanmış bir yapı, yeni özellik eklerken eski kodu kırma riskini azaltır ve ekibin projeyi daha rahat anlamasını sağlar.

Araştırma Kaynakları ve İleri Okuma

Paylaş