83 lines
3.1 KiB
C#
83 lines
3.1 KiB
C#
using AMREZ.EOP.Domain.Entities.Tenancy;
|
|
using AMREZ.EOP.Domain.Shared.Tenancy;
|
|
using AMREZ.EOP.Infrastructures.Data;
|
|
using AMREZ.EOP.Infrastructures.Options;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace AMREZ.EOP.Infrastructures.Tenancy;
|
|
|
|
/// <summary>
|
|
/// โหลดค่า Tenants / Domains ที่ IsActive=true จาก meta.* ใส่ TenantMap ตอนสตาร์ต
|
|
/// และ bootstrap 'public' ถ้ายังไม่มี
|
|
/// </summary>
|
|
public sealed class TenantMapLoader : IHostedService
|
|
{
|
|
private readonly IServiceProvider _sp;
|
|
public TenantMapLoader(IServiceProvider sp) => _sp = sp;
|
|
|
|
public async Task StartAsync(CancellationToken ct)
|
|
{
|
|
using var scope = _sp.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
var map = scope.ServiceProvider.GetRequiredService<TenantMap>();
|
|
var opt = scope.ServiceProvider.GetRequiredService<IOptions<AuthOptions>>().Value;
|
|
|
|
// 1) Load tenants (active เท่านั้น)
|
|
var tenants = await db.Set<TenantConfig>()
|
|
.AsNoTracking()
|
|
.Where(x => x.IsActive)
|
|
.ToListAsync(ct);
|
|
|
|
foreach (var t in tenants)
|
|
{
|
|
map.UpsertTenant(
|
|
t.TenantKey,
|
|
new TenantContext
|
|
{
|
|
Id = t.TenantKey,
|
|
Schema = string.IsNullOrWhiteSpace(t.Schema) ? t.TenantKey : t.Schema,
|
|
ConnectionString = string.IsNullOrWhiteSpace(t.ConnectionString) ? null : t.ConnectionString,
|
|
Mode = t.Mode
|
|
}
|
|
);
|
|
}
|
|
|
|
// 2) Load domains (active เท่านั้น)
|
|
var domains = await db.Set<TenantDomain>()
|
|
.AsNoTracking()
|
|
.Where(d => d.IsActive)
|
|
.ToListAsync(ct);
|
|
|
|
foreach (var d in domains)
|
|
{
|
|
if (d.IsPlatformBaseDomain)
|
|
{
|
|
map.AddBaseDomain(d.Domain);
|
|
}
|
|
else if (!string.IsNullOrWhiteSpace(d.TenantKey))
|
|
{
|
|
map.MapDomain(d.Domain, d.TenantKey!);
|
|
}
|
|
}
|
|
|
|
// 3) Bootstrap 'public' ถ้ายังไม่มี (กัน chicken-and-egg)
|
|
if (!map.TryGetBySlug("public", out _))
|
|
{
|
|
map.UpsertTenant(
|
|
"public",
|
|
new TenantContext
|
|
{
|
|
Id = "public",
|
|
Schema = "public",
|
|
ConnectionString = string.IsNullOrWhiteSpace(opt.DefaultConnection) ? null : opt.DefaultConnection,
|
|
Mode = TenantMode.Rls
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken ct) => Task.CompletedTask;
|
|
} |