
下面就以一个简单的例子来演示实现方式之一,即发件箱模式。
public abstract class IEntity
{
private int id;
public virtual int Id
{
get { return id; }
protected set { id = value; }
}
private List<IEvent> _domainEvents;
public IReadOnlyCollection<IEvent> DomainEvents => _domainEvents?.AsReadOnly(;
public void AddDomainEvent(IEvent eventItem
{
_domainEvents = _domainEvents ?? new List<IEvent>(;
_domainEvents.Add(eventItem;
}
public void RemoveDomainEvent(IEvent eventItem
{
_domainEvents?.Remove(eventItem;
}
public void ClearDomainEvents(
{
_domainEvents?.Clear(;
}
}
public class CreateOrderEvent:IEvent { public Guid EventId { get; set; } public int CustomerId { get; set; } public CreateOrderEvent(Guid EventId,int customerId { this.EventId = EventId; CustomerId = customerId; } }
我把事件简化到实体类里面,也可以不需要这个IEntity,那每次都需要自己创建order的同时创建一个事件,当然事件集合需要自己定义存起来。
这里的邮件就是事件了,而投递就是事件发布。
我新建一个order,同时把发布的order事件存到数据,这就是发件箱模式。好多数据库和中间件操作的最终一致性大体都是这个模式,借助数据库的分布式事务。
public sealed class OutBoxMessageInterceptor:SaveChangesInterceptor
{
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default
{
DbContext? dbContxt = eventData.Context;
if (dbContxt is null
{
return base.SavingChangesAsync(eventData, result, cancellationToken;
}
var events = dbContxt.ChangeTracker.Entries<IEntity>(.Select(x => x.Entity.SelectMany(x =>
{
List<IEvent> entiti