Oren’s recent posts on the Repository pattern and ORM have raised a hornets nest and intense discussion on the pattern itself. You can read them @: Repository is the new singleton, Mocking NHiberante and The DAL should go all the way to UI. In this post I’ll give my 2 cents on the points made in Oren’s post.
Lets start with the post: Repository is the new singleton. Now I had a very similar discussion with Oren a few weeks back and judging by the comments in that post my reaction was quite similar. I have had some time to think about this though… First of all I do completely agree with the point that the Repository pattern has become somewhat a focal point for DDD purists and is a pattern treated with much reverence. Data access has become such a major point that we have religious arguments on what a repository is and how we should implement it, what methods go into that, the infrastructure behind it and on and on it goes. The dry fact is that data access is the least interesting part in an application and it needs to be treated with that same emotion. You definitely need a standard, testable and mockable data access strategy that works for your application.
Now, one the first reasons I started NCommon was because I hated the fact of creating separate repository implementation for your aggregate roots, and more to the point that repositories should really represent a queryable data store that doesn’t abstract away queries behind methods that some unfortunate developer has to maintain and evolve, but rather allow consumers of the repository to query it directly. Hence why NCommon relies on repositories to implement the IQueryable interface to provide a query infrastructure directly on top of NCommon repositories.
Another point I also quite frankly agree with is that DDD is not required in all scenarios and standardizing on the repository pattern as your answer to all your data access strategies. Sometimes you can use a plain ORM directly without needing a repository providing an additional layer of abstraction over it. If your application is simple enough I’d suggest skipping a repository layer all together.
Now the second part goes into describing Oren’s approach of encapsulating complex queries using a Query object that takes in an ISession and an ICriteria to build up the encapsulated query. This is where I have a different opinion than the approach he described. The approach I would take is rather than exposing the infrastructure requirements in the query object, I’d like it to take in an IQueryable and return back a IQueryable. This will allow chaining of queries by multiple of such Query objects without exposing any infrastructure concerns.
Which is a nice segue to the last post: The DAL should go all the way to UI. This post gives a nice diagram of how we think of our traditional applications and for the most part I agree with it. Again, what I have a hard time accepting is the leak of infrastructure concerns. The problem with exposing ICriteria, or any other infrastructure component, to all layers of the application is that eventually a lot of infrastructure concern creeps into layers of the application where they don’t belong. I dislike the idea of having the expose ICriteria to the UI for adding paging and sorting on top of the query encapsulated by ICriteria.
That being said, in my opinion IQueryable is best suited for this job. Its a framework level member that is infrastructure agnostic, provides a very nice way to chain queries together and encapsulates our query requirements rather well. I’ve had comments and questions on NCommon forums before on why IRepository requires to implement the IQueryable interface as opposed to the more traditional approach of pre defined query methods… well Oren’s post quite nicely describes why. IQueryable allows queries on a repository to be augmented and further filtered by other layers.
Am I pimpin NCommon in this post??
Absolutely not. NCommon is a set of patterns and approaches that I feel are the direction I want to use for my future applications. I’m not suggesting that NCommon handles the approaches described in Oren’s post and in this one correctly. Rather, there are many areas where NCommon falls short, one being a detached criteria like functionality (something I am working on, more on this in a future post).
This post is a call to arms and say let querying be a exposed to all layers of an application rather than a careful and controlled encapsulation behind a rigid IRepository interface. Let our repositories be free!
Allowing ad-hoc querying across the layers of your application is a good thing, and it’s something I’d recommend to anyone. Getting caught up in the “what is a DAL layer” topic is not going to provide any value to your application, rather it’s going to end up adding complexity in your application where you don’t need to. As our technologies and frameworks have evolved allowing us to do more with less, similarly our patterns must evolve. I think we can end the rigid repository pattern for a more open, pluggable and extensible repository pattern.