I already have a SaveChangesInterceptor which is responsible for updating Audit Properties like Created date, CreatedBy, LastModified and LastModifiedBy. here is the Auditable Code snippet:
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
UpdateEntities(eventData.Context);
return base.SavingChangesAsync(eventData, result, cancellationToken);
}
public void UpdateEntities(DbContext? context)
{
if (context == null) return;
foreach (var entry in context.ChangeTracker.Entries<BaseAuditableEntity>())
{
if (entry.State == EntityState.Added)
{
entry.Entity.Created = _dateTime.Now;
entry.Entity.CreatedBy = _currentUserService.UserId;
}
if (entry.State == EntityState.Added || entry.State == EntityState.Modified || entry.HasChangedOwnedEntities())
{
entry.Entity.LastModified = _dateTime.Now;
entry.Entity.LastModifiedBy = _currentUserService.UserId;
}
}
}
I want to add another SaveChangesInterceptor which will be responsible to convert hard delete to soft delete by setting IsDeleted Property to true here is the soft delete Code snippet:
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
SoftDeleteEntities(eventData.Context);
return base.SavingChangesAsync(eventData, result, cancellationToken);
}
public void SoftDeleteEntities(DbContext? context)
{
if (context == null) return;
var deletedEntries = context.ChangeTracker
.Entries<BaseAuditableSoftDeletableEntity>()
.Where(entry => entry.State == EntityState.Deleted)
.ToList();
foreach (var entry in deletedEntries)
{
entry.State = EntityState.Modified;
entry.Entity.IsDeleted = true;
}
}
and here is the dependency injection
services.AddScoped<AuditableEntitySaveChangesInterceptor>();
services.AddScoped<SoftDeletableEntitySaveChangesInterceptor>();
the execution enters the Auditable Interceptor but not goes through Soft Delete Interceptor
I registered the Interceptor to DbContext according to @Svyatoslav comment and it works, the code will be like the following
private readonly AuditableEntitySaveChangesInterceptor _auditableEntitySaveChangesInterceptor;
private readonly SoftDeletableEntitySaveChangesInterceptor _softDeletableEntitySaveChangesInterceptor;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(_auditableEntitySaveChangesInterceptor);
optionsBuilder.AddInterceptors(_softDeletableEntitySaveChangesInterceptor);
}