CQRS查询侧实施

时间:2016-08-29 19:05:36

标签: domain-driven-design cqrs

我有点困惑在哪里实现应用程序的查询端,atm我有下一个架构:

Product.UI.Web.Admin (MVC)
Product.Application
 -CommandHandlers (e.g OrdersCommandHandler)
 -Commands (e.g CreateOrder)
Product.Domain
 -Model (Behavior-rich models / repository interfaces)
Product.Infrastructure (Base interfaces / classes)
Product.Persistence
 -ReadModel (EF Generated models)
 --Implementation (Repository implementations: FindByID / Save)
  1. 我应该在Product.Application中放置Queries命名空间,他们应该直接从那里访问数据库吗? (UI< = Product.Application< = Database)
  2. 我应该创建新的程序集Product.Queries和Product.UI.Web.Admin应该直接访问它吗? (UI< = Product.Queries)
  3. 我应该在Product.Application中添加Queries命名空间还是创建新的Assembly Product.Reporting并让Application程序集通过Queries命名空间使用Reporting程序集? (UI< = Product.Application.Queries< = Product.Reporting)
  4. 所有三个解决方案都将DTO返回给UI。

    我正在考虑解决方案#3,因为在查询中使用域服务来构建结果很容易,而且它还会使用Product.Reporting作为数据访问可以使用ADO.Net,Entity Framework或NHibernate实现。或许我误解了一些事情。

    请指导我并帮我清理一下,谢谢。

    更新 我来到第四个变种。

    1. 创建 Product.Infrastructure.Queries 程序集,我有数据库(dbcotnext)& ReadModel(EF生成模型和通用查询接口)命名空间。
    2. 在Product.Application中添加了 DataModel 命名空间,我有DTO返回UI
    3. 在Product.Application中添加了查询命名空间,我实现了通用查询并使用dbcontext检索数据,映射到DTO并返回到UI。

2 个答案:

答案 0 :(得分:1)

我认为我只是在这里应用依赖性倒置原则,并且具有定义接口的Application.Queries和实现这些接口的Infrastructure.Queries。但是,我也看到基础设施问题直接涉及Application层。例如,这就是Vaughn Vernon在SaasOvation合作BC的com.saasovation.collaboration.application.calendarCalendarEntryQueryService中所做的。

答案 1 :(得分:0)

  

我正在考虑解决方案#3,因为在查询中使用域服务很容易构建结果,并且它将使用Product.Reporting作为数据访问,可以使用ADO.Net,Entity Framework或NHibernate实现。或许我误解了一些事情。

是的,我也认为你误解了一些事情。

首先让我们谈谈域名服务是什么?: 当你有一个域概念涉及多个实体,但你是 不确定哪个实体“拥有”该行为。它似乎并不属于任何一种。这种思维模式是强烈的 域服务需求指标。 因此,当您使用cqrs时,域服务存在于命令端,因此查询端无法访问域服务,实际上并且自然地它不需要域服务,因为查询端不执行任何操作业务逻辑。你应该记住Command端和Query端是完全独立的。

CQRS的另一个重要特征是,ReadModel可以使用ADO.Net或微ORM等低级数据访问技术,并通过士气低落的表格查询生成报告。所有这些想法都是出于性能考虑。随着系统的发展,将来你甚至可以在两个独立的实例上启动Command和Query。