views:

406

answers:

2

Hi,

I am looking at implementing the repository pattern (since what I came up with was 90% an implementation of it anyway), and have come across a design question - where I have two or more core business objects (for example, Business and Contact in a CRM app), the BO's can be strongly related or not related at all.

In this situation, should I implement one repository (CrmRepository for example, with .addBusiness(), .addContact() et al), or multiple repositories (BusinessRepository, ContactRepository each with their own .add(), .delete() et al).

What is the best practice in this situation?

The underlying DAL is EF4.

Regards

Moo

+3  A: 

We have been doing a lot of thinking recently at my work and came across a few articles that helped us visualize and design our repositories in a consistent manner.

From what we found out one of the better practices is to create one repository per aggregate root. An aggregate root would be an Entity type where you need to reference that entity type to reach child value types. Only an Entity type could be queried from the database and any child Value types would need to be traversed from the Entity.

With your information in your question it seems like a Business would be an aggregate root and thus an Entity Type and would require its own repository. Since Contact can live independently that might be an aggregate root as well. Both objects could have references to each other and use a repository to load up the Businesses from a Contact or Load up the Contacts from a Business via its respective repository.

I have been doing a lot of reading recently so i hope I made some sense in my thought process.

Some links

Aggregate Root

Entities, Value Objects, Aggregates and Roots

Mark
+2  A: 

I totally agree with Mark on this, but to add a little more. As you look at the benefits of creating a Generic Repository, the common patter is IRepository and Repository. One thing I've found to be much more useful, brought to light by Jeremy D. Miller (can't find the reference) is having generics at the method level.

So my IReposity will have methods like this:

T FindByKey<T>(int key);
IEnumerable<T> FindAll();
T FindBy<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression);
void Update<T>(entity);

Then, depending on your philosophy, you can pass around the Repository class and query it directly, or make your Repository implementation abstract and force it's use to be encapsulated by an explicit repository, like this:

CrmRepository : Repository
{
   FindByCustomerId(int customerId)
   { return FindByKey<Customer>(customerId);}
}
Corey Coogan