I have a Category and Product tables in database and classes on project.

Category class has {id, Name} properties
Product class has {id, Name, CategoryId} and other relations.

And I have repository and service layer.

So if I need to get products of a category, where can I put this logic?

Category repository => GetProductsInThisCategory()

Product repository => GetProductsByCategory(CategoryId)

Is there any rule to separate like this logic.


(I guess GetProductsInThisCategory is not intended to be a repo method, but a category method, correct me if I am wrong).

Both is possible, and even a solution where you have both at the same time. A Product will probably know its category, so GetProductsByCategory(CategoryId) will often make sense, as Product already depends on Category. Introducing a Category method GetProductsInThisCategory() will imply that Category also depends on Product, so it leads to a cyclic dependency (which is often acceptable, not necessarily a bad solution, but if that causes problems in your environment or overall architecture, avoid it).

Assumed the cyclic dependency is not a problem, I recommend to implement the method or methods which lead to the shorter code at the components which use that methods. If you are going to implement both, because you expect client code which can make use of both methods in a meaningful way, implement one in terms of the other method to avoid duplicated logic, for example:

     return prodRepo.GetProductsByCategory(this.ID);

This gives the user of your system a little bit more "syntactic sugar" without adding too much additional code.

  • This cycle was my problem. I think the magic solution is "Product knows its Category" in your answer. Category knows Products in object related model, but product knows category in relational database model. Object related model requires lazy loading. And this is a bad solution for big data. So I will use GetProductsByCategory(CategoryId) – barteloma Nov 8 '16 at 13:12

You might easily find yourself in a situation when you need to implement both differently and at different levels. Simple example is GetProductsByCategory as a 'technical' method returning a collection of products with this CategoryId, but GetProductsInThisCategory as a 'business' method additionally applying sorting and filtration.

If methods behavior is the same - you already have an answer from Doc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.