我应该在 DDD 架构中的什么地方放置读取模型?
Where should I place read models in the DDD architecture?
目前我正在学习没有事件溯源的 CQRS 和 DDD(还没有)。我需要 return 从我的存储库到查询处理程序一个不同于域模型的模型。
我应该在域项目中创建读取模型吗?我需要在存储库(基础设施项目)、存储库接口中使用此读取模型(一个域项目)和一个查询处理程序(一个应用程序项目)?
进一步说明:
在我的数据库中,我有 table 个帖子与 table 个评论相关。 table评论中有一个外键:PostId。
这是我项目中的领域模型,你可以看到 Comment:
中没有 PostId
public class Post : Entity, IAggregateRoot
{
public Guid PostId { get; private set; }
public string Title { get; private set; }
public string Content { get; private set; }
public List<Comment> Comments { get; private set; }
}
public class Comment : Entity
{
public Guid CommentId { get; private set; }
public string Author { get; private set; }
public string Content { get; private set; }
}
我想从我的存储库中 return 评论,其中不仅包含 CommentId
、Author
、Content
,还包含 PostId
和 PostTitle
。这是我的存储库:
public class CommentsRepository : ICommentsRepository
{
private readonly ApplicationDbContext _applicationDbContext;
public CommentsRepository(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public async Task<Comment> GetByIdAsync(Guid id)
{
var comment = await _applicationDbContext.Comments
.SingleOrDefaultAsync(x => x.CommentId == id);
return comment;
}
}
我应该创建一个模型 CommentReadModel
(具有属性:CommentId
、Author
、Content
、PostId
和 PostTitle
)和在存储库中写入 SQL 以填充该模型?如果是,我应该将该模型放在哪里,因为 3 个项目将需要它:
- DomainProject(有接口:
ICommentsRepository
)
- InfrastructureProject(有实现:
CommentsRepository
)
- ApplicationProject(有一个调用存储库的查询处理程序)
??
你当然应该把你的阅读模型放在领域层。在实现应用程序的读取端时,您还应该摒弃任何复杂性。存储库在使用写入模型(聚合)时很好,因为它们可以封装一些基础设施逻辑(例如域事件调度、日志记录等)。您在读取端不需要任何这些功能。只需在您的查询处理程序中使用 Entity Framework 的(或 Dapper 的)引擎并直接获取数据,或者如果您愿意,可以在它们之上实现一些轻量级查询外观。
您还可以在 CQRS 应用程序中阅读这篇关于 query-side 的 Microsoft article。
目前我正在学习没有事件溯源的 CQRS 和 DDD(还没有)。我需要 return 从我的存储库到查询处理程序一个不同于域模型的模型。 我应该在域项目中创建读取模型吗?我需要在存储库(基础设施项目)、存储库接口中使用此读取模型(一个域项目)和一个查询处理程序(一个应用程序项目)?
进一步说明:
在我的数据库中,我有 table 个帖子与 table 个评论相关。 table评论中有一个外键:PostId。 这是我项目中的领域模型,你可以看到 Comment:
中没有 PostIdpublic class Post : Entity, IAggregateRoot
{
public Guid PostId { get; private set; }
public string Title { get; private set; }
public string Content { get; private set; }
public List<Comment> Comments { get; private set; }
}
public class Comment : Entity
{
public Guid CommentId { get; private set; }
public string Author { get; private set; }
public string Content { get; private set; }
}
我想从我的存储库中 return 评论,其中不仅包含 CommentId
、Author
、Content
,还包含 PostId
和 PostTitle
。这是我的存储库:
public class CommentsRepository : ICommentsRepository
{
private readonly ApplicationDbContext _applicationDbContext;
public CommentsRepository(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public async Task<Comment> GetByIdAsync(Guid id)
{
var comment = await _applicationDbContext.Comments
.SingleOrDefaultAsync(x => x.CommentId == id);
return comment;
}
}
我应该创建一个模型 CommentReadModel
(具有属性:CommentId
、Author
、Content
、PostId
和 PostTitle
)和在存储库中写入 SQL 以填充该模型?如果是,我应该将该模型放在哪里,因为 3 个项目将需要它:
- DomainProject(有接口:
ICommentsRepository
) - InfrastructureProject(有实现:
CommentsRepository
) - ApplicationProject(有一个调用存储库的查询处理程序) ??
你当然应该把你的阅读模型放在领域层。在实现应用程序的读取端时,您还应该摒弃任何复杂性。存储库在使用写入模型(聚合)时很好,因为它们可以封装一些基础设施逻辑(例如域事件调度、日志记录等)。您在读取端不需要任何这些功能。只需在您的查询处理程序中使用 Entity Framework 的(或 Dapper 的)引擎并直接获取数据,或者如果您愿意,可以在它们之上实现一些轻量级查询外观。
您还可以在 CQRS 应用程序中阅读这篇关于 query-side 的 Microsoft article。