ITLab.Template.DevPack.Infrastructure.EfCore.Interceptors
Implements EF Core SaveChanges interceptors for cross-cutting persistence behaviors.
Componentes
| Tipo | Nome | Responsabilidade |
|---|---|---|
| Class | AuditableEntityInterceptor | Applies created/updated metadata for IAuditable entities before each save |
| Class | SoftDeleteInterceptor | Converts hard deletes to soft-delete updates for ISoftDeletable entities |
| Class | MultiTenantEntityInterceptor | Stamps IMultiTenant.TenantId on insert and blocks cross-tenant modify/delete |
| Class | DispatchDomainEventsInterceptor | Publishes and clears domain events from tracked entities after save |
Como usar
// Interceptors are additive and can be chained.
options.AddInterceptors(
auditableInterceptor,
softDeleteInterceptor,
dispatchDomainEventsInterceptor);
MultiTenantEntityInterceptor — stamping + guard (10.5.0)
Write-side da tenancy, par do read-side global query filter (MultiTenantModelBuilderExtensions, ver ../README.md):
- Insert: entidade
IMultiTenantcomTenantIdnulo/0 recebe o tenant corrente via reflexão (ObjectHelper.TrySetProperty, mesma mecânica deEntityHelper.TrySetTenantId). Defesa em profundidade além do ctorEntity(). - Modify/Delete cross-tenant: se
TenantId != tenant corrente, lançaInvalidOperationException— o filtro de leitura não cobre uma entidade carregada num escopo e salva em outro. - Sem tenant corrente (
null/0= host/global): no-op.
services.AddDevPackEfCoreInterceptors()
.WithAuditableEntityInterceptor()
.WithSoftDeleteInterceptor()
.WithMultiTenantInterceptor() // após soft-delete, antes do dispatch
.WithDispatchDomainEventsInterceptor();
Como os demais, é Singleton e resolve ICurrentUser de um escopo por-call.
O que não fazer
- Do not depend on interceptor side effects for business invariants.
- Do not publish integration events directly in
DispatchDomainEventsInterceptorwithout outbox guarantees. - Do not rely on
MultiTenantEntityInterceptorfor read isolation — it is write-side only; pair it withApplyMultiTenantQueryFilters.
Extensão pelo produto
- Products can override behavior by replacing registrations with custom interceptor implementations.
- If replacing, preserve the contracts of
IAuditableandISoftDeletableto keep consistency.