8000 Explanation for when to handle domain events may be incorrect? · Issue #757 · dotnet/eShop · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Explanation for when to handle domain events may be incorrect? #757

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
roelofsmn opened this issue Feb 24, 2025 · 0 comments
Open

Explanation for when to handle domain events may be incorrect? #757

roelofsmn opened this issue Feb 24, 2025 · 0 comments

Comments

@roelofsmn
Copy link

In the OrderingContext class there is the following method:

public async Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default)
  {
      // Dispatch Domain Events collection. 
      // Choices:
      // A) Right BEFORE committing data (EF SaveChanges) into the DB will make a single transaction including  
      // side effects from the domain event handlers which are using the same DbContext with "InstancePerLifetimeScope" or "scoped" lifetime
      // B) Right AFTER committing data (EF SaveChanges) into the DB will make multiple transactions. 
      // You will need to handle eventual consistency and compensatory actions in case of failures in any of the Handlers. 
      await _mediator.DispatchDomainEventsAsync(this);

      // After executing this line all the changes (from the Command Handler and Domain Event Handlers) 
      // performed through the DbContext will be committed
      _ = await base.SaveChangesAsync(cancellationToken);

      return true;
  }

I'm wondering if the explanation in the comments of this method is correct, given that the commands are handled through a PipelineBehavior TransactionBehavior, which has the following Handle method:

public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
    ...
    try
    {
        ...
        await strategy.ExecuteAsync(async () =>
        {
            Guid transactionId;

            await using var transaction = await _dbContext.BeginTransactionAsync();
            using (_logger.BeginScope(new List<KeyValuePair<string, object>> { new("TransactionContext", transaction.TransactionId) }))
            {
                ...
                response = await next();
                ...
                await _dbContext.CommitTransactionAsync(transaction);
                transactionId = transaction.TransactionId;
            }
            await _orderingIntegrationEventService.PublishEventsThroughEventBusAsync(transactionId);
        });
        return response;
    }
    catch (Exception ex)
    {
        ...
        throw;
    }
}

And, as explained in the EF Core docs, using the BeginTransactionAsync method makes that any subsequent call to SaveChangesAsync becomes part of the same transaction.

So, in this situation, it wouldn't matter whether await _mediator.DispatchDomainEventsAsync(this); was called before or after await base.SaveChangesAsync(cancellationToken);, right? Or what am I misunderstanding / missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant
0