The repository pattern seems to work well when working with an initial project with several large main tables.
However as the project grows it seems a little inflexible. Say you have lots of child tables that hang off the main table, do you need a repository for each table?
E.g.
CustomerAddress Record has following child tables:
-> County
-> Country
-> CustomerType
On the UI, 3 dropdown lists need to be displayed, but it gets a bit tedious writing a repository for each of the above tables which selects the data for the dropdowns.
Is there a best practice/more efficient way of doing this?
As an example say you have a main CustomerAddress repository which I guess is the ‘aggregate root’ which inherits the main CRUD operations from the base repo interface.
Previously I have short-cutted the aggregate root and gone straight to the context for these kinds of tables.
e.g.
public Customer GetCustomerById(int id)
{
return Get(id);
}
public IEnumerable<Country> GetCountries()
{
return _ctx.DataContext.Countries.ToList();
}
etc…
But sometimes it doesn’t feel right, as countries aren’t part of the customer, but I feel like I need to tack it onto something without having to create zillions of repos for each table. A repo per table definately doesn’t seem right to me either.
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?