Backend/e-suite.Database.Audit/e-suite.Database.Audit/AuditableEntityContext.cs

74 lines
2.7 KiB
C#

using e_suite.Database.Audit.AuditEngine;
using e_suite.Database.Audit.Extensions;
using e_suite.Database.Audit.Tables.Audit;
using eSuite.Core.Clock;
using Microsoft.EntityFrameworkCore;
namespace e_suite.Database.Audit;
public abstract class AuditableEntityContext : DbContext, IAudit
{
private readonly AuditEngineCore _auditEngine;
private readonly IClock _clock;
protected AuditableEntityContext(DbContextOptions options, IClock clock) : base(options)
{
_clock = clock;
_auditEngine = new AuditEngineCore(this, clock);
}
public DbSet<AuditDetail> AuditDetails { get; set; } = null!;
public DbSet<AuditEntry> AuditEntries { get; set; } = null!;
public DbSet<AuditDrillHierarchy> AuditDrillHierarchies { get; set; } = null!;
public virtual async Task<int> NoAuditSaveChangesAsync()
{
return await NoAuditSaveChangesAsync(default!);
}
public virtual async Task<int> NoAuditSaveChangesAsync(CancellationToken cancellationToken)
{
return await SaveChangesAsync(cancellationToken);
}
public virtual async Task<int> SaveChangesAsync(AuditUserDetails auditUserDetails)
{
return await SaveChangesAsync(auditUserDetails, default);
}
private new async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
{
return await base.SaveChangesAsync(cancellationToken);
}
public virtual async Task<int> SaveChangesAsync(AuditUserDetails auditUserDetails, CancellationToken cancellationToken)
{
var auditEntries = _auditEngine.OnBeforeSaveChanges(this, auditUserDetails, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
var result = await base.SaveChangesAsync(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
_auditEngine.OnAfterSaveChanges(this, auditEntries, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
await base.SaveChangesAsync(cancellationToken);
return result;
}
public virtual async Task<int> AddAdhocAuditEntry(AuditUserDetails auditUserDetails, AuditType auditType, Dictionary<string, Change> fields, CancellationToken cancellationToken)
{
var auditEntries = new List<AuditRecorder>();
var auditEntry = new AuditRecorder(null, auditUserDetails, _clock)
{
AuditType = auditType
};
auditEntry.Fields.AddRange(fields);
auditEntries.Add(auditEntry);
_auditEngine.OnAfterSaveChanges(this, auditEntries, cancellationToken);
return await base.SaveChangesAsync(cancellationToken);
}
}