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;
}
}
}
}
Приклад реалізації на мові С#
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);
}
}