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); } }