Skip to main content
DiyanetCleanArchitecture.Infrastructure.EFCore projesi persistence (kalıcılık) katmanıdır. Domain aggregate’lerini PostgreSQL’e map eder, migration’ları üretir/uygular, audit + soft-delete davranışını tek bir interceptor üzerinden otomatikleştirir ve başlangıç verisini (seed) yazar.

Rolü

  • Tek DbContext: DiyanetCleanArchitectureDbContext : DbContext, IUnitOfWork — tüm aggregate’lerin DbSet’leri burada.
  • EntityTypeConfiguration’lar: Her aggregate için ayrı IEntityTypeConfiguration<T> (Fluent API). OnModelCreating bunları assembly’den reflection ile toplar.
  • Migration’lar: Migrations/ klasörü — EF Core code-first.
  • Interceptor: AuditInterceptor : SaveChangesInterceptorCreatedAt/By, UpdatedAt/By, soft-delete.
  • Repository’ler: EFRepository<T> (write, Ardalis.Specification tabanlı), CachedRepository<T> (read, HybridCache decorator).
  • Seed servisleri: DevDataSeeder (bootstrap admin), DistrictSeeder (973 ilçe), Fluent HasData (Role/RolePermission/Permission).

Teknoloji

BileşenSeçim
VeritabanıPostgreSQL 16 (dev: docker postgres:16)
ProviderNpgsql.EntityFrameworkCore.PostgreSQL 10.0.1
EF Core10.0.7
NamingEFCore.NamingConventions 10.0.1 → UseSnakeCaseNamingConvention()
SpecificationArdalis.Specification.EntityFrameworkCore 9.3.1
Outbox/InboxMassTransit.EntityFrameworkCore 8.5.9
UseSnakeCaseNamingConvention() sayesinde C# FullName → kolon full_name, RolePermission → tablo role_permission olur. EntityConfiguration’larda çoğu yerde HasColumnName açıkça yazılır; convention ise default davranıştır.

Şemalar

İki PostgreSQL şeması kullanılır:
public const string DEFAULT_SCHEMA   = "public";    // business aggregate'leri
public const string MESSAGING_SCHEMA = "messaging"; // MassTransit outbox/inbox
messaging şeması, MassTransit’in EF Core Outbox/Inbox tablolarını (inbox_state, outbox_state, outbox_message) business tablolarından ayrı tutar. Böylece infrastructure messaging detayı public şemasını kirletmez.
Hangfire ayrı bir hangfire şeması kullanır ama bu, EFCore projesinin değil Infrastructure.Jobs.Hangfire projesinin sorumluluğundadır.

Klasör yapısı

DiyanetCleanArchitecture.Infrastructure.EFCore/
├── DiyanetCleanArchitectureDbContext.cs
├── DependencyInjection.cs                       # AddInfrastructureEFCore
├── MigrationService.cs                          # IHostedService — AutoDeploy migrate
├── DiyanetCleanArchitectureDesignTimeDbContextFactory.cs
├── DesignTimeDbContextFactoryBase.cs            # appsettings okur (dotnet ef için)
├── Interceptors/
│   └── AuditInterceptor.cs                      # audit + soft-delete
├── Repositories/
│   ├── EFRepository.cs                          # write — IRepository<T>
│   ├── EFCacheRepository.cs                     # read kaynağı (cache'siz)
│   ├── CachedRepository.cs                      # IReadRepository<T> decorator
│   ├── RolePermissionRepository.cs
│   └── UserContextRepository.cs
├── EntityConfigurations/                        # IEntityTypeConfiguration<T>
│   ├── UserConfigurations/
│   ├── RoleConfigurations/
│   ├── CitizenConfigurations/
│   └── ...                                      # her aggregate için bir klasör
├── Migrations/                                  # EF Core migration'lar + snapshot
└── SeedWork/
    ├── DevDataSeeder.cs                         # bootstrap admin (config-driven)
    ├── DistrictSeeder.cs                        # Districts.csv → 973 ilçe
    ├── MediatorExtension.cs                     # DispatchDomainEventsAsync
    ├── IAuditUserContext.cs                     # audit aktör kimliği
    └── MigrationOptions.cs                      # Services:Migration:AutoDeploy

SaveChanges akışı

AuditInterceptor SaveChanges anında devreye girer; domain event dispatch ise SaveEntitiesAsync içinde SaveChanges sonrası çalışır. Detaylar ilgili sayfalarda.

Bu bölümde

DbContext & Repository

DbSet’ler, OnModelCreating, value object map’leme, EFRepository / CachedRepository, UnitOfWork.

Migrations

dotnet ef komutları, DesignTime factory, MigrationService AutoDeploy, migration listesi.

Audit Interceptor

AuditInterceptor, IAuditUserContext, OnConfiguring’e eklenme nedeni.

Soft Delete

ISoftDeletable, global query filter, restore, partial unique index.

Seed Data

DevDataSeeder, DistrictSeeder, HasData, prod davranışı.