Class EfCoreAggregateDataSource
- Namespace
- Savvyio.Extensions.EFCore.Domain
- Assembly
- Savvyio.Extensions.EFCore.Domain.dll
Provides an implementation of the EfCoreDataSource that is optimized for Domain Driven Design and the concept of Aggregate Root.
public class EfCoreAggregateDataSource : EfCoreDataSource, IDisposable, IEfCoreDataSource, IDataSource, IUnitOfWork
- Inheritance
-
EfCoreAggregateDataSource
- Implements
- Derived
- Inherited Members
Examples
EfCoreAggregateDataSource<TContext> is the domain-scoped EF Core data source that implements IEfCoreDataSource and restricts context usage to aggregate root operations. Subclass it with the specific DbContext type to provide a named aggregate context factory. The example wires up a minimal aggregate context and confirms it resolves from the data source.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Savvyio.Domain;
using Savvyio.Extensions.EFCore;
using Savvyio.Extensions.EFCore.Domain;
namespace ExampleApp;
public sealed class OrderingWorkflow
{
public async Task<int> SaveOrderAsync()
{
var dispatcher = new RecordingDomainEventDispatcher();
var source = new OrderingDataSource(dispatcher, new EfCoreDataSourceOptions
{
ContextConfigurator = builder => builder.EnableDetailedErrors(),
ModelConstructor = modelBuilder => modelBuilder.Entity<OrderAggregate>().HasKey(order => order.Id)
});
var repository = new EfCoreAggregateRepository<OrderAggregate, Guid>(source);
repository.Add(OrderAggregate.Place(Guid.NewGuid(), "PO-2048"));
await source.SaveChangesAsync();
return dispatcher.Published.Count;
}
}
public sealed class OrderingDataSource : EfCoreAggregateDataSource
{
public OrderingDataSource(IDomainEventDispatcher dispatcher, EfCoreDataSourceOptions options) : base(dispatcher, options)
{
}
}
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;
Constructors
EfCoreAggregateDataSource(IDomainEventDispatcher, DbContext)
Initializes a new instance of the EfCoreAggregateDataSource class.
protected EfCoreAggregateDataSource(IDomainEventDispatcher dispatcher, DbContext dbContext)
Parameters
dispatcherIDomainEventDispatcherThe IDomainEventDispatcher that are responsible for raising domain events.
dbContextDbContextThe DbContext to associate with this data store.
EfCoreAggregateDataSource(IDomainEventDispatcher, EfCoreDataSourceOptions)
Initializes a new instance of the EfCoreAggregateDataSource class.
public EfCoreAggregateDataSource(IDomainEventDispatcher dispatcher, EfCoreDataSourceOptions options)
Parameters
dispatcherIDomainEventDispatcherThe IDomainEventDispatcher that are responsible for raising domain events.
optionsEfCoreDataSourceOptionsThe EfCoreDataSourceOptions used to configure this instance.
Methods
SaveChangesAsync(Action<AsyncOptions>)
Saves the different IRepository<TEntity, TKey> implementations as one transaction towards a data store asynchronous.
public override Task SaveChangesAsync(Action<AsyncOptions> setup = null)
Parameters
setupAction<AsyncOptions>The AsyncOptions which may be configured.
Returns
Remarks
Will, just before SaveChangesAsync(CancellationToken) is called, extract and call RaiseAsync(IDomainEvent, Action<AsyncOptions>) for all aggregate roots contained within the backing DbContext.