What is best practise for repository pattern - repo per table?

六月ゝ 毕业季﹏ 提交于 2019-12-03 13:37:34

I would certainly not create a repository per table. On the contrary: I would define one generic repository that works for every table. By doing this you save yourself a lot of code, and when you implement IQueryable on that class, it will allow you to use LINQ queries over it, and you can hide your O/RM framework behind an abstraction, which allows you to effectively write unit tests. I wrote an article on this, see Faking your LINQ provider.

First the code you posted is not the repository pattern. Where is the collection like interface? If it is an aggregate it should only be returning the aggregate type.

Repository pattern doesn't offer up much flexibility when it comes being able to select different types. Repository pattern follows a collection interface (insert/add/update/delete/get/etc), mirroring an in memory thing, and it generally only retrieves on type. So if you were to use the repository pattern you would need to select all CustomerAddresses and then* filter the countries out. I would suggest you move to a different pattern, that allows for more flexibility aka DAO.

If these things are always going to be maintained through CustomerAddress, then switch patterns and create a DAO class that offers some other getters for the other types of things you need.


On a more generic note, build for need.

Never just blindly create repository classes, its a maintenance nightmare. The only time I would argue for a repo per table is when you are doing CMS like things, and need to be able create everything.

Example:

So you have a CustomerAddress which ties together a Customer and a Country, but you have some other process that needs to be able to CRUD the Country. As a result you need* the repository to manipulate Country and if you are following DRY you dont want to have duplicate logic to manipulate Countries. What you would have is a Customer Respotitory that uses the Country repository.

I'm answering my own question here because while the suggestions are certainly useful, I feel I have a better solution. While I don't have to phsyically create the underlying repository for each and every table as I have a generic repository base class with interface (Get, Add, Remove), I still have to:

1) write the interface to access any specialised methods (generally these are queries)

2) write those implementations

I don't necessarily want to do this when all I want to retrieve is a list of countries or some simple type for populating a dropdown. Think of effort required if you have 10 reference type tables.

What I decided to do was create a new class called SimpleRepo with ISimpleRepo interface which exposes 1-2 methods. While I don't normally like to expose the IQueryable interface out of the repo i/f class, I don't mind here as I want the provided flexibility. I can simply expose a 'Query()' method which provides the flexibility hook. I might need this for specialising the ordering, or filtering.

Whenever a service needs to make use of some simple data, the ISimple< T > interface is passed in, where T is the table/class.

I now avoid the need to create an interface/class for these simple pieces of data. Thoughts anyone?

Nicholas Petersen

Responding to the questioner's own answer: This doesn't make sense to me; though it's possible you still had a good use case, I'm not following. Points 1 and 2 ... if you need specialized methods, then looks like they belong in their own repo. Point 2: yes, that needs an implementation.

Sharing between repos, with the smaller repo being the question (is that one needed), I do appreciate that question / problem, but guys' on this thread steered me to being okay with 1 repo per table, including the possibility of having a 'service layer', though they didn't give any examples of that, and I haven't tried this out yet (currently my practice, for good or ill, has been to have the bigger repo share or instantiate the smaller one it needs):

One repository per table or one per functional section?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!