我正在实现域驱动设计(DDD)体系 struct ,并希望为我的实体利用强类型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); 

        // ...
    }
}

如果事先不知props 体的TId类型,我如何修改我的PublishDomainEvents()方法或相关方法以使其与AggregateRoot<TId>一起工作?我想维护类型安全和强类型ID的好处.

提前感谢您的帮助,干杯!:)

推荐答案

因为你的拦截器代码实际上不需要使用强类型的ID,所以最简单的 Select 是为AggregateRoot<TId>引入一个非泛型接口来实现和使用它:

public interface IAggregateRoot
{
   public IEnumerable<IDomainEvent> DomainEvents { get; }
}

public abstract class AggregateRoot<TId>
    : Entity<TId>, IAggregateRoot
    where TId : struct
{
    // ...
}

和用法:

var entities = context.ChangeTracker
    .Entries<IAggregateRoot>() 
    .Where(e => e.Entity.DomainEvents.Any())
    .Select(e => e.Entity); 

Csharp相关问答推荐

ß != ss与ICU进行不区分大小写的比较

System.Data.SQLite:判断SQLite数据库是否为空(任何表中至少有一行)

错误NU 1301:无法加载源的服务索引

有没有一种方法可以防止在编译时在MicrosoftC或非单线程上下文中调用方法?

Azure Function应用(. NET 8)不将信息记录到应用洞察

C#.NET依赖项注入顺序澄清

如何从ASP.NET核心MVC视图和Blazor传递数据

从ASP.NET Core中的枚举字段填充 Select 选项时,将默认的第一个选项添加为 Select 元素

如何在毛伊岛应用程序中完美地同步视图模型和视图的加载?

如何注册类使用多级继承与接口

C#中浮点数的System.Text.Json序列化问题

如果是,我怎么才能让这个加75,如果不是,我怎么才能减go 100?

对于PowerShell中的ConvertTo-SecureString方法,Microsoft如何将初始化向量添加到AES加密中的安全字符串?

仅在ASP.NETCore应用程序中的附加单独端口上公开一组终结点

如何在Xamarin.Forms中检索PanGesture事件的位置?

将两个for循环更改为一条LINQ语句

将列表转换为带有逗号分隔字符串形式的值的字典

与另一个对象位于同一位置的对象具有不同的变换位置

我想我必须手动使用res1(字符串形式的PowerShell哈希表)

LINQ在GROUP BY和JOIN之后获取子列表