我正在实现领域驱动设计 (DDD) 架构,并希望为我的实体利用强类型 ID。我的基础
AggregateRoot
类看起来像这样:
public abstract class AggregateRoot<TId>
: Entity<TId>
where TId : struct
{
private readonly List<IDomainEvent> _domainEvents = [];
// ...
}
这是一个示例实体:
public readonly record struct AuctionId(Guid Value);
public class Auction
: AggregateRoot<AuctionId>
{
// ...
}
我有一个域事件调度程序拦截器(
PublishDomainEventsInterceptor
),我希望它可以与所有聚合一起工作:
internal sealed class PublishDomainEventsInterceptor
: SaveChangesInterceptor
{
// ...
public async Task PublishDomainEvents(
DbContext? context)
{
// ...
// Problem: Need a generic way to handle strongly-typed IDs here
var entities = context.ChangeTracker
.Entries<AggregateRoot>() // Issue: Requires type argument
.Where(e => e.Entity.DomainEvents.Any())
.Select(e => e.Entity);
// ...
}
}
如何在事先不知道具体
PublishDomainEvents()
类型的情况下修改我的 AggregateRoot<TId>
方法或相关方法以使其与 TId
一起使用?我想保持类型安全和强类型 ID 的好处。
提前感谢您的帮助,干杯! :)
由于您的拦截器代码实际上不需要使用强类型 Id,最简单的选择是引入一个非通用接口来实现和使用它:
AggregateRoot<TId>
及用法:
public interface IAggregateRoot
{
public IEnumerable<IDomainEvent> DomainEvents { get; }
}
public abstract class AggregateRoot<TId>
: Entity<TId>, IAggregateRoot
where TId : struct
{
// ...
}