I think my interface is very well defined and with the XMLDoc comments easy to follow what will be implemented. The most notable changes from my original post is the removal of the GetAll and GetRange methods that returned an ICriteria, these always felt like a kludge to me as they clearly bleed concern by allowing the raw ICriteria to be exposed however back then I didn’t have the tools and knowledge available to create a better solution.

The new methods are related to the DetachedCriterias QuerySingle, QueryList and to the Future based queries FutureSingle and FutureList. Future is a newer construct in NHibernate that allows you to specify a query that you want NHibernate to understand and know at some point in the Future it will need this execution so you can batch more than 1 query together and reduce the number of calls to a database. This is a great bonus as the database is usually always the biggest slow down in an application.

This class houses the generic CRUD operations that are made generic to allow you to handle any custom object easily. The methods that are once again of interest are the ones I discussed as new additions to my Repository. The beauty of all them regardless is in their simplicity that they can all be written in 1 concise line yet offer immense flexibility.

With the QuerySingle and QueryList methods these allow you to take in a DetachedCriteria and get back either a single object or a IList collection which should be pretty self explanatory from both the code and method names.

The FutureList and FutureSingle are not so much as obvious. As I stated before these allow you to make these happen in the future. In my implementation only the FutureList will really allow you to relegate multiple events into the future but it also makes the most sense since individual lookups are frequently done by indexed columns that should be quick even done in multiple seperate calls. For each call you make to FutureList it will have NHibernate queue up the specified DetachedQuery and wait for one of the following either code causes any of IEnumerables returned to be enumerated which will fire off 1 mulit-query to get all of the result sets or you call FutureSingle.

FutureSingle is some what of a more unusual animal because a regular object doesn’t have the lazy access method that IEnumerables do either it exists, or it doesn’t. There is no transient stage as there is with IEnumerables. To overcome this fact the developers of NHibernate created this transient stage by wrapping object with a generic interface for IFutureValue<T> this gives a construct to have a 3rd stage that you need to call .Value to invoke the actual execution which will process all future queries. In my repository I actually call .Value immediately on a DetachedCriteria being passed into this, why? Because I’d need to return a IFutureValue<T> instead of just T as the result from the method. This in my opinion would be just as much of a kludge as returning ICriteria was from my previous implementation as it bleeds NHibernate understanding logic outside of the repository. This purely a subjective point and if you disagree with my sentiment you could easily return IFutureValue<T> and have a wider range of flexibility with the Future support.

Now on to actual usage of this in a real world scenario. I am going to be taking advantage of a framework I recently learned about called NHibernate Lambda Expressions this allows you to write Criteria and DetachedCriteria queries without the need to rely on magic strings. The point of this post won’t be to cover the usage of this as it should be mostly understandable for my example.

If you look at my GetPersons method you should see I have a somewhat deep object graph that is realistic, I have a collection of Persons in my database where I assign them a zip code object that contains among other things the zip code and the state that zip code lives in. I create a DetachedCriteria that lets me find all persons that exist in a state and I pass that down to my generic IRepository by delegation instead of inheritance. Many examples similar to my post use inheritance where you will inherit from Repository<Person> instead of having a delegate inside of a non generic class I feel this is the wrong way because it then limits you to having 1 repository per data object instead of being able to drop multiple IRepositorys inside of a single DataProvider.

Taking this a step further I can even remove the need to ever create a physical implementation of Repository<Person> through the use of an inversion of control / dependency injection framework in this case specifically StructureMap. In literally 1 line I can create an infinite amount of IRepositories for any application I need.

This instructs StructureMap that anytime I need a IRepository<Person> or any other data object that it’s to give it a usage of Repository
completely absolving me of the responsibility of defining a Repository<Person> combining the functionality I’ve outlined in this post it offers a broad range of usage that allows you to interact with NHibernate without ever needing to write a single line of code again except the specific DetachedCriterias which will need written in one shape or form irregardless because they will have custom sql be the end result of them and to just wire up Methods to allow access to the underlying CRUD methods. You could actually expose the generic methods themselves however I feel that is exposing too much logic to be available to an API and prefer to shroud my generic repositories in the classes I call DataProviders as it also lets me group repositories in meaningful ways.