An Opinion on Repository
Posted almost 3 years ago on July 06, 2009
First, what is a repository?
…Therefore, use a Repository, the purpose of which is to
encapsulate all the logic needed to obtain object references. The
domain objects won’t have to deal with the infrastructure to get
the needed references to other objects of the domain. They will
just get them from the Repository and the model is regaining its
clarity and focus.
Excerpt from Domain Driven Design Quickly
So what the author is saying is that the repository’s (single) responsibility is to encapsulate the logic for obtaining object references. What that means to me is that the class utilizing the repository should be querying it in clear terms, such as:
_repository.GetPendingOrdersFor(customer);
This interface keeps the behavior of the method calling the repository focused on it’s job, and eliminates querying logic. Not only that, but the intention of the code is clear and even human(non-developer) readable.
The alternative is:
_respository.Query<Order>(o => o.CustomerID = customer.CustomerID && o.Status == OrderStatus.Pending);
Here’s how these options would look as an interface.
Just one man’s opinion. What do you think?
Comments
Jon Kruger writes...
The way I see it, the single responsibility of the Repository is to perform operations on a data store (CRUD operations using an ORM, calling stored procs, etc.) The repository itself should not have any business logic in it -- that goes in a domain service.
So in your example, I would change IOrderRepository to something like IOrderService, IGetOrderService, or IGetPendingOrdersService (depending on how granualar you want to get with it). The domain service would not derive from IBaseRepository<T>, but would take an IBaseRepository<T> in as a constructor parameter so that it could perform the query.
July 06, 2009
Steve Horn writes...
@Jon
So why not just have your service layer just take a dependency on NHibernate's ISession, or Linq To SQL's DataContext? It doesn't seem like the repository really buys you anything...other than adding a layer of indirection so swapping out ORM implementations can be achieved.
July 06, 2009
Jon Kruger writes...
You're not the first person to say that. :)
http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx
I still like the repository, but maybe I'm just used to it. My repository class mostly just calls into NHibernate's ISession, but it's allowed me to abstract some stuff away (like setting FlushMode on the session, hiding NHibernate's query stuff inside methods with nice names, etc.).
It's not like it's a lot more work to have a repository in there. It's one file that I wrote one time and I pretty much never change it, but it allows me the flexibility to override the default behavior if I ever need to.
Will I ever need to? I might not. But I think having the extensibility point is worth it especially since it didn't really cost me anything to put it in.
July 07, 2009
New Comment