views:

383

answers:

2

Hi

Im confused. This is a blog entry of Ayende Rahien Repository is the new singleton.

I believe that a repository should only do CRUD operations and not addtional queries otherwise youll end up with methods like these on your repository.

  1. FindCustomer(id)
  2. FindCustomerWithAddresses(id)
  3. FindCustomerWith..

So my question is, where(in what layer) would one do the queries to retrieve entities?

+1  A: 

It's possible to write repository which have default CRUD operations. For example:

public interface IRepository<TEntity>
{
   TEntity FindByIdentity(object identity);
   TEntity FindBy(Expression<Func<TEntity, bool>> specification);
   IList<TEntity> FindAll();
   IList<TEntity> FindAllBy(Expression<Func<TEntity, bool>> specification);
   TEntity Save(TEntity saveable);
   void Delete(TEntity deletable);
}

Expression> is basically Specification and queries can be encapsulate that way. If we have that kind of Repository then we don't need to write many specific repositories.

Alternative path is create Query object. We could add interface of that query to Core/Busines Logic layer and implementation to Services/Data layer. That way we have nicely named queries like AllPreferredCustomersQuery. It's quite similar to specifications, but specifications don't use infrastructure and therefore we may add it to Core/Business Logic layer. Query objects are more configurable (e.g. possible to add limits, fetching strategies, joins etc.)

Marek Tihkan
+3  A: 

Two useful posts on the subject: by Jimmy Bogard and by Greg Young.

I gravitate towards a hybrid approach: generic repositories for simple actions and query objects for more complicated ones. I usually don't expose repositories to whatever is using my logic (UI, service), but offer functionality in a service-/facade-like pattern, so the dual-approach is not exposed outside of this facade layer.

tijmenvdk