Table of Contents

Class DomainEventDispatcherExtensions

Namespace
Savvyio.Extensions.EFCore.Domain
Assembly
Savvyio.Extensions.EFCore.Domain.dll

Extension methods for the IDomainEventDispatcher interface.

public static class DomainEventDispatcherExtensions
Inheritance
DomainEventDispatcherExtensions

Examples

DomainEventDispatcherExtensions.RaiseMany and RaiseManyAsync iterate over the domain events accumulated on an IAggregateRoot after a save operation and dispatch each event through IDomainEventDispatcher. Inject IDomainEventDispatcher into the repository, call the save operation, and then call RaiseManyAsync with the saved aggregate. The example shows a save-then-raise pattern using an EF Core–backed order repository.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Savvyio.Domain;
using Savvyio.Extensions.EFCore.Domain;

namespace ExampleApp;

public sealed class DomainEventWorkflow
{
    public async Task<int> PublishPendingEventsAsync()
    {
        var dispatcher = new RecordingDomainEventDispatcher();
        var context = new OrdersContext();
        var order = OrderAggregate.Place(Guid.NewGuid(), "PO-1024");

        context.Orders.Add(order);

        dispatcher.RaiseMany(context);
        dispatcher.RaiseManyAsync(context).GetAwaiter().GetResult();

        await Task.CompletedTask;
        return dispatcher.Published.Count;
    }
}

public sealed class OrdersContext : DbContext
{
    public DbSet<OrderAggregate> Orders => Set<OrderAggregate>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<OrderAggregate>().HasKey(order => order.Id);
    }
}

public sealed class RecordingDomainEventDispatcher : IDomainEventDispatcher
{
    public List<IDomainEvent> Published { get; } = new();

    public void Raise(IDomainEvent request)
    {
        Published.Add(request);
    }

    public Task RaiseAsync(IDomainEvent request, Action<Cuemon.Threading.AsyncOptions>? setup = null)
    {
        Published.Add(request);
        return Task.CompletedTask;
    }
}

public sealed class OrderAggregate : Aggregate<Guid, IDomainEvent>, IAggregateRoot<IDomainEvent, Guid>
{
    private OrderAggregate()
    {
    }

    private OrderAggregate(Guid id, string orderNumber) : base(id)
    {
        OrderNumber = orderNumber;
        AddEvent(new OrderPlaced(orderNumber));
    }

    public string OrderNumber { get; private set; } = string.Empty;

    public static OrderAggregate Place(Guid id, string orderNumber)
    {
        return new OrderAggregate(id, orderNumber);
    }
}

public sealed record OrderPlaced(string OrderNumber) : DomainEvent;

Methods

RaiseMany(IDomainEventDispatcher, DbContext)

Raises domain events from the specified context to handlers that implements the IDomainEventHandler interface.

public static void RaiseMany(this IDomainEventDispatcher dispatcher, DbContext context)

Parameters

dispatcher IDomainEventDispatcher

The IDomainEventDispatcher to extend.

context DbContext

The DbContext to extract aggregate(s) and publish domain events from.

RaiseManyAsync(IDomainEventDispatcher, DbContext, Action<AsyncOptions>)

Asynchronously raises domain events from the specified context to handlers that implements the IDomainEventHandler interface.

public static Task RaiseManyAsync(this IDomainEventDispatcher dispatcher, DbContext context, Action<AsyncOptions> setup = null)

Parameters

dispatcher IDomainEventDispatcher

The IDomainEventDispatcher to extend.

context DbContext

The DbContext to extract aggregate(s) and publish domain events from.

setup Action<AsyncOptions>

The AsyncOptions which may be configured.

Returns

Task

A Task that represents the asynchronous operation.