7.2 KiB
.NET / ABP Kod Standardı
Bu doküman api/ altındaki tüm projeler için bağlayıcıdır. Platform davranışına dair
kurallar için ai.instructions.md esastır; çelişki olursa o dosya kazanır.
Standart derlemede zorlanır: api/Directory.Build.props analizörleri açar,
api/.editorconfig kural şiddetlerini tanımlar. Bu iki dosya standardın tek
kaynağıdır; proje dosyalarında tekrar edilmez.
1. Hedef sürümler
| Katman | Sürüm | Nerede tanımlı |
|---|---|---|
| SDK | .NET 10 (10.0.300) |
api/global.json |
| TargetFramework | net10.0 |
proje dosyaları |
| Dil | C# 14 (LangVersion=latest) |
api/common.props |
| ABP | 10.0.0 | Volo.Abp.* paket referansları |
Sürüm yükseltmesi tek noktadan yapılır: global.json + common.props + paket sürümleri.
Proje dosyalarına TFM/LangVersion tekrar yazılmaz.
2. Nullable
Directory.Build.props içinde çözüm geneli Nullable ayarı yapılmaz. Sebebi
EF Core: kolonun zorunlu olup olmadığını, entity assembly'sinin nullable annotation
bağlamından türetir. Global bir enable/annotations anahtarı, bir sonraki
dotnet ef migrations add çağrısında tüm string özelliklerini sessizce NOT NULL
kolona çevirir — seeder'ın doldurmadığı her alan da o anda kırılır.
Kural:
- Nullable, proje bazında ve bilinçli olarak açılır (
<Nullable>enable</Nullable>). Şu an açık olanlar:Sozsoft.Platform.Application,Sozsoft.Notifications.*, test projeleri. - Entity taşıyan projelerde (
*.Domain) nullable açılacaksa, aynı PR'dadotnet ef migrations addçıktısı gözden geçirilir; şema değişikliği isteniyorsa kabul edilir, istenmiyorsa kolon zorunluluğuPlatformDbContextiçinde.IsRequired(false)ile açıkça sabitlenir. - Kolon zorunluluğu tercihen NRT'ye değil,
PlatformDbContextyapılandırmasına yazılır; böylece derleyici anahtarından bağımsız olur.
3. Ölü kod politikası
Aşağıdaki kurallar ihlal edilmiş kod merge edilmez:
| Kural | Anlamı |
|---|---|
| IDE0005 | Kullanılmayan using |
| IDE0051 | Çağrılmayan private üye |
| IDE0052 | Yazılıp hiç okunmayan private alan (kullanılmayan enjekte bağımlılık) |
| IDE0059 | Gereksiz değer ataması |
| IDE0161 | namespace X; (file-scoped) |
Tarama ve otomatik düzeltme (kalıcı yapılandırma gerektirmez):
# Rapor
dotnet build api/Sozsoft.Platform.sln --no-incremental \
-p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
# Düzeltme
dotnet format api/Sozsoft.Platform.sln --diagnostics IDE0005,IDE0161 --severity warn
Kurallar
.editorconfig'tewarningseviyesindedir veEnforceCodeStyleInBuildaçık olduğu için normaldotnet buildde bunları raporlar.
IDE0052 düzeltilirken alan ile birlikte constructor parametresi de silinir; yoksa DI hâlâ gereksiz servisi çözer.
CS0162 (erişilemez kod) Directory.Build.props içinde gerekçesiyle susturulmuştur:
veritabanı sağlayıcısı derleme zamanı sabiti olduğu için diğer sağlayıcının dalları
erişilemez görünür. Bu durum dışında erişilemez kod bırakılmaz.
Ek kurallar:
- Bir tip/dosya silinmeden önce repo genelinde (api + ui + configs) referans taraması yapılır. DI ile çözülen tipler (AppService, Manager, Provider, Repository, Seeder, Localizer, Notification sağlayıcıları) düz metin aramasında "referanssız" görünür — bunlar yalnızca modül/DI kaydı incelendikten sonra silinir.
- Yorum satırına alınmış kod bloğu bırakılmaz; ihtiyaç varsa git geçmişinden alınır.
- "İleride lazım olur" gerekçesiyle kullanılmayan DTO/Input/Consts tutulmaz.
Migrations/ve*.g.csüretilmiş koddur, bu kuralların dışındadır.
4. Modern C# kullanımı (yeni kod)
- File-scoped namespace:
namespace Sozsoft.Platform.ListForms; - Primary constructor:
public class XAppService(IRepository<X, Guid> repo) : PlatformAppService— parametre doğrudan kullanılır,private readonly ... = param;şeklinde tekrar tanımlanmaz. - Koleksiyon ifadeleri (
[],[.. items]),is not null,switchifadesi, desen eşleme,Index/Range, hedefi bellinew(). out var, tuple deconstruction; kullanılmayan çıktı için_.asyncmetotlarAsyncile biter veTask/Task<T>döner;async voidyasak. ABP'deConfigureAwaitkullanılmaz.- Biçim:
api/.editorconfiggeçerlidir (4 boşluk girinti,usingblokları namespace dışında ve System önce, dosya sonunda satır sonu, UTF-8 BOM).
5. ABP kuralları
- Katman sınırı: Domain.Shared → Domain → Application.Contracts → Application →
HttpApi → HttpApi.Host. Ters yönde referans verilmez;
EntityFrameworkCoreyalnızca Domain'e bakar. - AppService:
PlatformAppService'ten türer, arayüzü Application.Contracts'ta tanımlanır. Controller yazılmaz — ABP otomatik API üretir. Controller sadece ABP konvansiyonunun karşılamadığı durumda (dosya indirme, harici webhook) eklenir. - Yetki: her AppService/metot
[Authorize(PlatformConsts.AppCodes....)]ile korunur; izin adlarıPermissionDefinitionProvideriçinde tanımlanır. Yetki kontrolü koda gömülmez, izin adı sabitten okunur. - Tenant izolasyonu: sorgular
ICurrentTenantbağlamında çalışır;IMultiTenantentity'lerde manuelTenantIdfiltresi yazılmaz, veri filtreleri devre dışı bırakılacaksa (ICurrentTenant.Change,IDataFilter) gerekçe yorumla yazılır. - Repository: özel sorgu gerekiyorsa Domain'de arayüz + EntityFrameworkCore'da
implementasyon. AppService içinde
DbContextdoğrudan kullanılmaz. - Dinamik SQL: parametreli çalıştırılır; string birleştirme ile sorgu kurulmaz.
- Mapping: Mapperly (
[Mapper]partial class) kullanılır; AutoMapper eklenmez. RMG012 uyarısı "hedefte karşılığı olmayan alan" demektir; yeni mapper eklerken bu uyarı bırakılmaz. - Localization: kullanıcıya görünen metin koda gömülmez,
PlatformResourceanahtarı üzerinden verilir. - Çok değerli alan taşıyan girdi DTO'su: ekranda
dxTagBox(ya da çoklu seçimlidxGridBox) ile doldurulan bir alan tipli bir DTO'ya bağlanıyorsa propertystringkalır ve[JsonConverter(typeof(MultiValueStringJsonConverter))]ile işaretlenir — UI diziyi olduğu gibi yollar, converterPlatformConsts.MultiValueDelimiterile tek string üretir. Varsayılanlist-form-data/*ucundan geçen ekranlarda bu işQueryHelpertarafından yapılır, DTO yoktur; okuma DTO'larına öznitelik eklenmez. - Sabitler: bağlantı dizesi, tenant id, anahtar/secret koda yazılmaz; konfigürasyon
veya
SettingDefinitionüzerinden okunur.
6. Değişiklik öncesi kontrol listesi
dotnet build api/Sozsoft.Platform.sln --no-incremental \
-p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true # 0 hata, yeni IDE00xx yok
dotnet format api/Sozsoft.Platform.sln --verify-no-changes --diagnostics IDE0005,IDE0161 --severity warn
dotnet test api/test/Sozsoft.Platform.EntityFrameworkCore.Tests
Not: EntityFrameworkCore testleri şu an SQLite şema oluşturmada (
nvarchar(max)→SQLite Error 1) kırık; bu kırıklık bu standarttan önce de vardı ve ayrı bir iş olarak ele alınmalıdır.