57 lines
2.6 KiB
C#
57 lines
2.6 KiB
C#
using System.Collections.Concurrent;
|
|
using AMREZ.EOP.Abstractions.Applications.Tenancy;
|
|
using AMREZ.EOP.Domain.Shared.Tenancy;
|
|
|
|
namespace AMREZ.EOP.Infrastructures.Tenancy;
|
|
|
|
/// <summary>
|
|
/// ศูนย์รวม mapping แบบไดนามิก:
|
|
/// - Tenants: slug/key -> TenantContext
|
|
/// - DomainToTenant: custom-domain -> tenantKey
|
|
/// - BaseDomains: ชุดโดเมนแพลตฟอร์มที่รองรับรูปแบบ *.basedomain (รองรับหลายอันได้)
|
|
/// คุณสามารถเติม/แก้ไขระหว่างรันงานผ่าน Admin API หรือ job reload จาก DB ได้เลย
|
|
/// </summary>
|
|
public sealed class TenantMap
|
|
{
|
|
private readonly ConcurrentDictionary<string, TenantContext> _tenants = new(StringComparer.OrdinalIgnoreCase);
|
|
private readonly ConcurrentDictionary<string, string> _domainToTenant = new(StringComparer.OrdinalIgnoreCase);
|
|
private readonly ConcurrentDictionary<string, byte> _baseDomains = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
// ====== Query ======
|
|
public bool TryGetBySlug(string slug, out ITenantContext ctx)
|
|
{
|
|
if (_tenants.TryGetValue(slug, out var t))
|
|
{
|
|
ctx = t; return true;
|
|
}
|
|
ctx = null!; return false;
|
|
}
|
|
|
|
public bool TryGetByDomain(string domain, out ITenantContext ctx)
|
|
{
|
|
if (_domainToTenant.TryGetValue(domain, out var key) && _tenants.TryGetValue(key, out var t))
|
|
{ ctx = t; return true; }
|
|
ctx = null!; return false;
|
|
}
|
|
|
|
public bool TryGetBaseDomainFor(string host, out string? baseDomain)
|
|
{
|
|
foreach (var kv in _baseDomains.Keys)
|
|
{
|
|
var bd = kv;
|
|
if (host.EndsWith(bd, StringComparison.OrdinalIgnoreCase) && !host.Equals(bd, StringComparison.OrdinalIgnoreCase))
|
|
{ baseDomain = bd; return true; }
|
|
}
|
|
baseDomain = null; return false;
|
|
}
|
|
|
|
// ====== Admin / Reload ======
|
|
public void UpsertTenant(string key, TenantContext ctx) => _tenants[key] = ctx;
|
|
public bool RemoveTenant(string key) => _tenants.TryRemove(key, out _);
|
|
|
|
public void MapDomain(string domain, string tenantKey) => _domainToTenant[domain.Trim().ToLowerInvariant()] = tenantKey;
|
|
public bool UnmapDomain(string domain) => _domainToTenant.TryRemove(domain.Trim().ToLowerInvariant(), out _);
|
|
|
|
public void AddBaseDomain(string baseDomain) => _baseDomains[baseDomain.Trim().ToLowerInvariant()] = 1;
|
|
public bool RemoveBaseDomain(string baseDomain) => _baseDomains.TryRemove(baseDomain.Trim().ToLowerInvariant(), out _);
|
|
} |