QuietNaN
QuietNaN

Reputation: 371

CQRS Query Side implementation

I am a bit confused where to implement query side of application, atm i have next architecture:

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. Should i place Queries namespace in Product.Application and they should directly access database from there? (UI <= Product.Application <= Database)
  2. Should i create new assembly Product.Queries and Product.UI.Web.Admin should access it directly? (UI <= Product.Queries)
  3. Should i add Queries namespace in Product.Application and also Create new Assembly Product.Reporting and let Application assembly use Reporting assembly via Queries namespace? (UI <= Product.Application.Queries <= Product.Reporting)

All three solutions return DTOs to UI.

I am thinking about solution #3 as it will be easy to use Domain Services in Queries to build results and also it will use Product.Reporting as Data Access which can be implemented using ADO.Net, Entity Framework or NHibernate. Or maybe i misunderstood something.

Please guide me and help me clear it up, thank you.

UPDATE I came to fourth variant.

  1. Created Product.Infrastructure.Queries assembly, there i have Database (dbcotnext) & ReadModel (EF Generated models & generic query interfaces) namespaces.
  2. Added DataModel namespace in Product.Application, there i have DTOs to return to UI
  3. Added Queries namespace in Product.Application, there i implement generic queries and use dbcontext to retrieve data, map to DTOs and return to UI.

Upvotes: 3

Views: 1034

Answers (2)

Masoud Sedghi
Masoud Sedghi

Reputation: 614

I am thinking about solution #3 as it will be easy to use Domain Services in Queries to build results and also it will use Product.Reporting as Data Access which can be implemented using ADO.Net, Entity Framework or NHibernate. Or maybe i misunderstood something.

yes I also think you misunderstood something.

firstly let's talk about what domain services are?: when you have a domain concept that involves multiple entities but you’re unsure about which entity “owns” the behavior. It doesn’t appear to belong to any of them.This pattern of thinking is a strong indicator of the need for a domain service. so when you are using cqrs, the domain services live in command side so the query side can not access to domain services, actually and naturally it doesn't need to domain services because the query side doesn't carry out any business logic.you should all time remember that Command side and Query side are completely independent.

another important characteristic of CQRS is that the ReadModel could use a low level data access techniques like ADO.Net or micro ORMs and query through demoralized tables for generate reports.all of this ideas is for performance considerations.furthmore as the system grows in future you could even launch Command and Query sides on two separate instance.

Upvotes: 0

plalx
plalx

Reputation: 43718

I think I'd just apply the dependency inversion principle here and have something like Application.Queries that defines interfaces and Infrastructure.Queries which implement these interfaces. However, I've also seen infrastructure concerns directly into the Application layer. For instance, this is what Vaughn Vernon did in com.saasovation.collaboration.application.calendarCalendarEntryQueryService of the SaasOvation collaboration BC.

Upvotes: 1

Related Questions