Add Login Module

This commit is contained in:
Thanakarn Klangkasame
2025-10-02 11:18:44 +07:00
parent f505e31cfd
commit 563a341a99
52 changed files with 1127 additions and 2036 deletions

View File

@@ -18,7 +18,6 @@ public sealed class EFUnitOfWork : IUnitOfWork, IAsyncDisposable
private readonly ITenantDbContextFactory _factory;
private readonly IConnectionMultiplexer? _redis;
private AppDbContext? _db;
private IDbContextTransaction? _tx;
private ITenantContext? _tenant;
@@ -31,40 +30,38 @@ public sealed class EFUnitOfWork : IUnitOfWork, IAsyncDisposable
{
_scope = scope;
_factory = factory;
_redis = redis; // optional; null ได้
_redis = redis;
}
public async Task BeginAsync(ITenantContext tenant, IsolationLevel isolation = IsolationLevel.ReadCommitted, CancellationToken ct = default)
{
if (_db is not null) return;
if (_tx is not null) return;
_tenant = tenant ?? throw new ArgumentNullException(nameof(tenant));
_scope.EnsureForTenant(tenant);
_db = _scope.Get<AppDbContext>();
_tx = await _db.Database.BeginTransactionAsync(isolation, ct);
var db = _scope.Get<AppDbContext>();
_tx = await db.Database.BeginTransactionAsync(isolation, ct);
}
public async Task CommitAsync(CancellationToken ct = default)
{
if (_db is null) return; // ยังไม่ Begin
if (_tx is null) return;
// track entities ที่เปลี่ยน (เพื่อ invalidate cache แบบแม่นขึ้น)
var changedUsers = _db.ChangeTracker.Entries<User>()
var db = _scope.Get<AppDbContext>();
var changedUsers = db.ChangeTracker.Entries<User>()
.Where(e => e.State is EntityState.Added or EntityState.Modified or EntityState.Deleted)
.Select(e => e.Entity)
.ToList();
var changedIdentities = _db.ChangeTracker.Entries<UserIdentity>()
var changedIdentities = db.ChangeTracker.Entries<UserIdentity>()
.Where(e => e.State is EntityState.Added or EntityState.Modified or EntityState.Deleted)
.Select(e => e.Entity)
.ToList();
await _db.SaveChangesAsync(ct);
await db.SaveChangesAsync(ct);
await _tx.CommitAsync(ct);
if (_tx is not null)
await _tx.CommitAsync(ct);
// optional: invalidate/refresh Redis (ล่มก็ไม่พัง UoW)
if (_redis is not null && _tenant is not null && (changedUsers.Count > 0 || changedIdentities.Count > 0))
{
var r = _redis.GetDatabase();
@@ -75,8 +72,6 @@ public sealed class EFUnitOfWork : IUnitOfWork, IAsyncDisposable
{
var keyId = $"eop:{tenantId}:user:id:{u.Id:N}";
tasks.Add(r.KeyDeleteAsync(keyId));
// refresh cache (ถ้าต้องการ)
var payload = JsonSerializer.Serialize(u);
var ttl = TimeSpan.FromMinutes(5);
tasks.Add(r.StringSetAsync(keyId, payload, ttl));
@@ -88,7 +83,7 @@ public sealed class EFUnitOfWork : IUnitOfWork, IAsyncDisposable
tasks.Add(r.KeyDeleteAsync(k));
}
try { await Task.WhenAll(tasks); } catch { /* swallow */ }
try { await Task.WhenAll(tasks); } catch { }
}
await DisposeAsync();
@@ -109,11 +104,9 @@ public sealed class EFUnitOfWork : IUnitOfWork, IAsyncDisposable
public ValueTask DisposeAsync()
{
try { _tx?.Dispose(); } catch { /* ignore */ }
try { _db?.Dispose(); } catch { /* ignore */ }
_tx = null; _db = null; _tenant = null;
try { _tx?.Dispose(); } catch { }
_tx = null;
_tenant = null;
return ValueTask.CompletedTask;
}
}