Auditable Entity (шаблон проєктування)
Auditable Entity — шаблон проєктування, який надає дані звітності про зміну стану сутності.
Опис ред.
Нехай, необхідно отримувати інформацію про зміну сутності. Додамо базовим клас, який містить цей необхідний функціонал.
public abstract class AuditableEntity
{
public DateTime CreatedAt { get; set; }
public string CreatedBy { get; set; }
public DateTime ModifiedAt { get; set; }
public string ModifiedBy { get; set; }
}
public class User : AuditableEntity
{
public string Name { get; set; }
}
Тоді при створені чи зміні сутності необхідно оновлювати значення цих полів. Зручно помістити цю логіку в одне місце, а не розкидувати по коду програми. Скористаємось одиницею роботи для цього.
public class UnitOfWork
{
private List<EntityEntry> _trackedEntities = new List<EntityEntry>();
public void Commit()
{
foreach (var entityEntry in _trackedEntitites.Select(x => x.Entity).OfType<AuditableEntity>())
{
switch (entry.State)
{
case EntityState.Added:
entry.Entity.CreatedBy = _currentUserService.GetUserId();
entry.Entity.CreatedAt = _dateTimeService.GetTime();
break;
case EntityState.Modified:
entry.Entity.ModifiedBy = _currentUserService.GetUserId();
entry.Entity.ModifiedAt = _dateTimeService.GetTime();
break;
}
}
}
}
Реалізація ред.
C# ред.
Приклад реалізації на мові С#
public class ApplicationDbContext : DbContext
{
private readonly ICurrentUserService _currentUserService;
private readonly IDateTimeService _dateTimeService;
public ApplicationDbContext(ICurrentUserService currentUserService, IDateTimeService dateTimeService)
{
_currentUserService = currentUserService;
_dateTimeService = dateTimeService;
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
foreach (EntityEntry<AuditableEntity> entry in ChangeTracker.Entries<AuditableEntity>())
{
switch (entry.State)
{
case EntityState.Added:
entry.Entity.CreatedBy = _currentUserService.GetUserId();
entry.Entity.Created = _dateTimeService.GetTime();
break;
case EntityState.Modified:
entry.Entity.LastModifiedBy = _currentUserService.GetUserId();
entry.Entity.LastModified = _dateTimeService.GetTime();
break;
}
}
return base.SaveChangesAsync(cancellationToken);
}
}