Closed carlsixsmith-moj closed 4 months ago
Why has this been closed without even a comment?
Do you have any good solutions for this? I haven't considered transactions; I just want to implement notifications to subscribers for create, update, and delete operations. Additionally, since the entity ID is auto-incremented, I need to obtain the ID of the newly created entity, as this is crucial for subsequent business operations.
I could generate a pull request for this if you'd think it's worth going in.
I've got it working in our solution using the below in the interceptor model.
public override async ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
var context = eventData.Context;
var domainEventEntities = context!.ChangeTracker
.Entries<IEntity>()
.Select(po => po.Entity)
.Where(po => po.DomainEvents.Any())
.ToList();
var domainEvents = domainEventEntities
.SelectMany(x => x.DomainEvents)
.ToList();
if (domainEvents.Any())
{
await using var transaction = await context.Database.BeginTransactionAsync(cancellationToken);
try
{
var saveResult = await base.SavingChangesAsync(eventData, result, cancellationToken);
foreach (var entity in domainEventEntities)
{
entity.ClearDomainEvents();
}
foreach (var e in domainEvents)
{
await mediator.Publish(e, cancellationToken);
}
await transaction.CommitAsync(cancellationToken);
return saveResult;
}
catch
{
await transaction.RollbackAsync(cancellationToken);
throw;
}
}
return await base.SavingChangesAsync(eventData, result, cancellationToken);
}
I am going to combine this with an outbox later so that we have two event types.
Consumed within the same database transaction (so auto generated Ids are not a problem as the EF tracker takes care of them
Some of the domain event listeners will add a message to an outbox (within the same transaction as the change you are making) to be picked up later by a background process and published to an external queue.
If either or both of these are interesting to you and this project I can fork and implement it here?
Sure, please create a pull request for this. I will review it and merge it."
The dispatching of domain events currently won't work if you want to change the state of a different entity in an event listener.
Domain events should be consistent within a bounded context at the moment they are fired AFTER the entity has been saved and they aren't wrapped in any form of transaction.
Is this a design choice or oversite?