dotnet / dotnet/eShop

Domain events should be published utill there are no more left

Open
#103 0 comments 2 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
10.9k
Forks
3.8k
Avg merge
1d 11h
Merged PRs (30d)
4

Description

Current implementation of [`eShop.Ordering.Infrastructure.MediatorExtension.DispatchDomainEventsAsync`](https://github.com/dotnet/eShop/blob/main/src/Ordering.Infrastructure/MediatorExtension.cs)
will check tracked entities and publish all domain event those entices hold once, which triggers domain event handlers to handle published events.
However, in real world applications, domain event handlers might also cause new domain events generated, and in current implementation new created domain events will be ignored.

I wrote this implementation that will keep publishing created domain events from tracked entires recursively, utill there are no more left. Please consider.

```cs
static class MediatorExtension
{
public static async Task DispatchDomainEventsAsync(this IMediator mediator, OrderingContext ctx)
{
bool remains = true;
while(remains) {
var publishedCount = await DispatchDomainEventsRecursivelyAsync(mediator, ctx);
remains = publishedCount > 0;
}
}

private static async Task DispatchDomainEventsRecursivelyAsync(this IMediator mediator, OrderingContext ctx)
{
var domainEntities = ctx.ChangeTracker
.Entries()
.Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any());

var domainEvents = domainEntities
.SelectMany(x => x.Entity.DomainEvents)
.ToList();
int count = domainEvents.Count;

domainEntities.ToList()
.ForEach(entity => entity.Entity.ClearDomainEvents());

foreach (var domainEvent in domainEvents)
await mediator.Publish(domainEvent);

return count;
}
}
```

Would be happy to create the PR.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.