Skip to main content
Clean Architecture’ın temel kuralı: bağımlılıklar içe doğru akar. Dış katmanlar iç katmanlara referans verir; iç katmanlar dış katmanları bilmez.

Referans grafiği

İzin verilen bağımlılıklar

KatmanŞunlara referans verebilirŞunlara veremez
DomainSharedKernelApplication, Infrastructure, API
Domain.SharedKernelBuildingBlocks.SpecificationDomain, Application, Infrastructure
ApplicationDomain, SharedKernel, BuildingBlocksAPI, doğrudan EF Core implementasyonu (arayüzler üzerinden)
Infrastructure.EFCoreDomain, SharedKernel, BuildingBlocksApplication iş mantığı, API
Infrastructure.Services.*SharedKernel, BuildingBlocksDomain iş kuralları, Application handler’ları
APIApplication + tüm Infrastructure + BuildingBlocks— (en dış katman)
Altın kural: DiyanetCleanArchitecture.Domain projesi hiçbir zaman using DiyanetCleanArchitecture.Infrastructure.* göremez. Domain dışa bağımlılığı arayüz (port) ile ifade eder; somut implementasyon Infrastructure’da yaşar ve Program.cs’te DI ile bağlanır.

Bağımlılık inversiyonu (DIP) nasıl uygulanır?

Application bir altyapı yeteneğine ihtiyaç duyduğunda arayüzü kendisi (veya SharedKernel) tanımlar, implementasyonu Infrastructure verir:
Arayüz (Application / SharedKernel)Implementasyon (Infrastructure)
IRepository<T>, IReadRepository<T>, IUnitOfWorkEFRepository<T>, CachedRepository<T>, DiyanetCleanArchitectureDbContext
IEmailServiceEmailService (Services.Email)
IOtpSmsServiceOtpSmsService (Services.Sms)
IEventBusMassTransitEventBus (BuildingBlocks.EventBus.MassTransit.RabbitMq)
IHybridRequestCacheHybridRequestCache (BuildingBlocks.Caching)
IUserFactory, IUserUniquenessCheckerUserFactory, UserUniquenessChecker
Böylece Application, somut Redis/RabbitMQ/SMTP sınıflarını değil, soyutlamaları kullanır; test edilebilirlik ve sağlayıcı değiştirilebilirliği kazanılır.

Domain saflığı (purity)

Domain ve SharedKernel’in dış dünyaya tek dokunuşu BuildingBlocks.Specification üzerinedir (Ardalis.Specification). Bu bilinçli bir tavizdir: sorgu tanımlarını (spec) Domain’de tutmak, repository imzalarını temiz tutar. Persistence detayı (EF Core) yine de Infrastructure’dadır.

Build sırası

MSBuild bağımlılık grafiğine göre sıralar:
SharedKernel  →  Domain  →  Application
                     ↘  Infrastructure.EFCore / Services.*  ↗
                                    ↘  API  ↙
İç katman değiştiğinde dış katmanlar yeniden derlenir; bu yüzden Domain/SharedKernel’de yapılan değişiklik en geniş etkiye sahiptir.

Sık yapılan hatalar

Bir aggregate içinde DbContext veya HTTP client kullanmaya çalışmak. Çözüm: ihtiyacı bir Domain Service arayüzüyle ifade et, implementasyonu Infrastructure’a koy.
EFRepository.SaveChangesAsync() bilinçli olarak exception fırlatır. Daima IUnitOfWork.SaveEntitiesAsync() kullanılır — domain event dispatch buna bağlıdır. Bkz. Veri Katmanı › DbContext.
BuildingBlocks yatay ve uygulamadan habersizdir. Application onları kullanır, tersi olmaz.