Given:
- You have an architecture with the layers presentation, business and data.
- You are applying domain-driven design.
- You are using an object-relational mapper that lets you create object-oriented queries (e.g., NHibernate which lets you create HQL queries).
Question:
Into which layer should you put the object-oriented queries?
My thoughts:
I think putting them into the presentation layer will usually make no sense. But I don't know whether to put them into business or data layer.
Example (NHibernate):
Say your business logic needs some method GetCustomersPossiblyInterestedIn(Product p). You might then create a complex HQL query that selects customer objects where the customer has already bought a product that is in the same category as p.
Argument a)
On the one hand, I'd say this query is clearly business logic, because the decision that a customer is treated as possibly interested in a product based on whether she has bought a product in the same category is a business decision. You might as well select customers who have bought multiple products in the same category with a similar price, e.g.
Argument b)
On the other hand, the business layer should not depend upon the data layer, so directly using NHibernate in the business layer rings an alarm bell.
Possible solution 1)
Create your own object-oriented query language that you use in the business layer and translate to HQL in the data layer. I think this would cause a lot of overhead. If you use a query language based on query objects instead of a parsed query language, you could probably safe some effort, but my objection still applies.
Possible solution 2)
Directly using NHibernate in the business layer is O.K., because the abstraction level that NHibernate is able to provide with HQL, ISession etc. fits the business layer. There is no need to wrap it.
What do you think?
Edits:
See "Repository is the new Singleton" and "The false myth of encapsulating data access in the DAL" by Ayende Rahien for closely related discussions.