1

I've been reading about the repository pattern and how to implement it correctly.

There is one important issue that I'm confused about.

Say we have a generic repository with basic operations like Add(), Remove(), GetById(), etc. and we also have a specific repository per entity (e.g. ProductRepository, UserRepository, etc.)

Should we define entity-related operations in the specific repositories or not? For example, in the ProductRepository, should I declare methods like GetProductsInCategory(), GetProductsByBrandId(), etc. or is this the responsibility of the service layer?

There is a lot of information out there that are against each other, as an example, this answer claims that the answer to the question that I just asked is No, but on the other hand in this tutorial video (which has a lot of views) the instructor claims that the answer to my question is Yes.

I'm really confused about the actual methods and operations that we have to implement in a repository.

Arad Alvand
  • 8,607
  • 10
  • 51
  • 71
  • This sounds like something that would be primarily opinion based. There is nothing in C# itself about this. Personally I would stick with the generic Add, etc, as the class name and function parameters and return types should make the types clear enough – fredrik Nov 13 '19 at 10:10
  • @fredrik Half of computer science and software engineering is opinion-based if you think about them like that! But in the case of this question, I don't think it's opinion-based, I think one group (that I mentioned) is probably mistaken and ignoring a key point about the repository pattern, I see both groups are certain about their own opinion, and they seem to have evidence for what they say is correct. – Arad Alvand Nov 13 '19 at 10:13
  • @AmirHosseinAhmadi aaaannnnnddd... you just described opinion based. – Jamiec Nov 13 '19 at 10:18

1 Answers1

1

Say we have a generic repository with basic operations like Add(), Remove(), GetById()

This is OK if those members are not exposed outside the Data Access Layer. Basically, avoid generic repository. But, as this is not your core of the question, I will not go into the details of it here.

and we also have a specific repository per entity (e.g. ProductRepository, UserRepository, etc.)

This is good practice.

Should we define entity-related operations in the specific repositories or not? For example, in the ProductRepository, should I declare methods like GetProductsInCategory(), GetProductsByBrandId(), etc.

Those functions must be part of specific repository. In fact, that is the purpose of existence of specific repository.

or is this the responsibility of the service layer?

This is opinion based.
Yes; you drop the complete repository layer and do all that stuff in services.
No; abstract the database logic in repositories and keep your services database agnostic. Let them focus on business logic.

So the choice is yours.

The answer you linked suggests alternative to avoid creating too many filter methods in repository.

Instead it is better to have a query method on the repository which takes a Specification. You can pass different implementations of the Specification to retrieve the products.

Although I personally do not agree with it (it leaks data access components in calling layer as you have to accept Specification instance from outside), it may be helpful where you have too much varying filter criteria.
Other point about that answer is that, apparently (that question is tagged as such), it is talking in terms of DDD. You have not mentioned DDD in your question.
In general, I do not agree with most of the claims that answer do; personally.

I'm really confused about the actual methods and operations that we have to implement in a repository.

Specific repositories should implement methods and operations that your calling layer need. If that layer need methods like GetProductsInCategory(), GetProductsByBrandId(), etc. you should implement those. As said above, this is the reason of existence of specific repositories.

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141