Geliştirilen yazılımların çoğu, birden fazla müşteriye (tenant) hizmet vermek üzere tasarlanır.
- Yazılım Uzmanları
- 08 Aralık 2024
- 57 kez görüntülendi.
Entity Framework Core’da Multi-Tenant (Çok Kiracılı) Mimariler
Giriş
Geliştirilen yazılımların çoğu, birden fazla müşteriye (tenant) hizmet vermek üzere tasarlanır. Bu tasarıma multi-tenant (çok kiracılı) mimari denir. Entity Framework Core (EF Core), bu tarz mimarileri desteklemek için esnek bir altyapı sunar. Bu makalede, EF Core kullanarak multi-tenant mimariler oluşturmanın temel yöntemlerini, uygulama örneklerini ve çözüm yollarını inceleyeceğiz.
Multi-Tenant Mimari Nedir?
Multi-tenant mimaride, birden fazla müüterinin (tenantın) verileri tek bir uygulama üzerinde tutulur. Ancak, bu verilerin birbiriyle karışmaması ve tenant bazında yönetilmesi gerekir. EF Core’da multi-tenant mimariler genellikle iki şekilde ele alınır:
-
Veritabanı Seviyesinde Ayrım: Her tenant için ayrı bir veritabanı oluşturulur.
-
Tablo Seviyesinde Ayrım: Tek bir veritabanı kullanılır, ancak veriler bir tenantın kimliğine (TenantId) göre filtrelenir.
Entity Framework Core ile Multi-Tenant Mimariler
1. Veritabanı Seviyesinde Ayrım
Bu yöntemde, her tenant için ayrı bir veritabanı kullanılır. EF Core, Connection String bazlı çalıştığı için her tenantın bağlantı bilgisini dinamik olarak ayarlayabilirsiniz.
Adımlar:
-
Connection String’i Dinamik Ayarla: Tenant bazında bağlantı bilgisini belirlemek için bir middleware ya da servis kullanabilirsiniz.
public class TenantDbContext : DbContext
{
private readonly IHttpContextAccessor _httpContextAccessor;
public TenantDbContext(DbContextOptions<TenantDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor = httpContextAccessor;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var tenantId = _httpContextAccessor.HttpContext?.Request.Headers["TenantId"];
var connectionString = GetConnectionStringForTenant(tenantId);
optionsBuilder.UseSqlServer(connectionString);
}
private string GetConnectionStringForTenant(string tenantId)
{
// Tenant’a özel connection string’i dönün.
return tenantId switch
{
"Tenant1" => "Server=server1;Database=Tenant1Db;...",
"Tenant2" => "Server=server2;Database=Tenant2Db;...",
_ => throw new Exception("Tenant bulunamadı")
};
}
}
-
Middleware ile Tenant Belirleme:
TenantId bilgisi genellikle HTTP isteklerinden gelir.
public class TenantMiddleware
{
private readonly RequestDelegate _next;
public TenantMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Headers.TryGetValue("TenantId", out var tenantId))
{
context.Items["TenantId"] = tenantId;
}
await _next(context);
}
}
2. Tablo Seviyesinde Ayrım
Bu yöntemde, her tenantın verisi aynı tabloda tutulur ancak her kayıt bir TenantId ile işaretlenir.
Adımlar:
-
TenantId’yi Modelınize Ekleyin:
Entity modellerinize TenantId alanı ekleyerek her kaydışı bir tenantın kimliğine bağlayabilirsiniz.
public class BaseEntity
{
public int Id { get; set; }
public string TenantId { get; set; } = string.Empty;
}
public class Product : BaseEntity
{
public string Name { get; set; }
public decimal Price { get; set; }
}
-
Global Query Filter Kullanın: EF Core’un global query filter özelliğini kullanarak her tenantın sadece kendi verilerini görebilmesini sağlayabilirsiniz.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().HasQueryFilter(p => p.TenantId == _tenantId);
}
-
TenantId’yi Dinamik Olarak Belirleyin:
TenantId bilgisi, genellikle HTTP isteklerinden ya da oturumdan alınır.
public class TenantService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public TenantService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string GetCurrentTenantId()
{
return _httpContextAccessor.HttpContext?.Request.Headers["TenantId"] ?? string.Empty;
}
}
Multi-Tenant Mimari Avantajları ve Dezavantajları
Avantajlar:
-
Verimlilik: Tek bir uygulama ile birden fazla tenant yönetilebilir.
-
Maliyet Tasarrufu: Aynı altyapı kullanıldığı için donanım ve lisans maliyetleri azalır.
-
Hızlı Yükseltme: Yeni bir tenant eklemek genellikle kolaydır.
Dezavantajlar:
-
Güvenlik: Verilerin tenantlar arasında karışmaması için ekstra önlem alınmalıdır.
-
Karmaşıklık: Tablo seviyesinde ayrım yapıldığında sorguları optimize etmek zor olabilir.
Sonuç
Entity Framework Core, multi-tenant mimariler kurmak için esnek bir altyapı sunar. Veritabanı seviyesinde ya da tablo seviyesinde ayrım yaparak tenant bazlı veri yönetimi sağlayabilirsiniz. Hangi yöntemi seçeceğiniz, projenizin gereksinimlerine ve ölçeklenebilirlik ihtiyacına bağlıdır. Yukarıdaki yöntemlerden birini uygulayarak yazılımızınızı multi-tenant destekli hale getirebilirsiniz.
Bu yazıya 0 yorum yapılmış.