In the previous tutorial set we looked at the Repository pattern and how one might use it to construct a support framework for Fluent NHibernate. If you looked at closely you likely realized some very serious and obvious design flaws. The main thing that I didn’t like about it was the use of the derived repositories and the constraints it placed on various user stories. For example, in order to save related items, or perform read operations, multiple repository instances were needed. This creates a huge burden on the developer. What is really needed in this case is a store, that is a single class that provides lazy loaded instances of the other repositories the system supports.
To begin this process, we first need to generate code. Our types are not known to use at any point until after a database is read. To do this we will use T4 templates. I will blog later on about creating these templates for now we are just working to understand the theory.
So the idea behind this reorganization is to create a single class that all other repositories work off. The repository instances for the specific models will need to provide enough extensibility to let developers take control of the save process, but also provide enough out of the box functionality so that it is useful without modification.
Furthermore, we want to encourage developers to use our single instance so we need to provide a way for their functions to be called in place of our original. To do this we will use abstract base classes with virtual methods. By defining a default save method as virtual in the base class we can provide the developer a way to override the function that is automatically called when a Commit is initiated on the store’s objects.
So the Store is generally in charge of initiating the Commit process via reflection and finding appropriately decorated properties that represent the Repositories. The commit is only called if the list is deemed to be dirty.
Each of the derived repositories can only hold objects of certain type, the type must inherit from EntityBase thereby insuring that the object being operated on is an Entity. Finally the Entity saving, deleting, and updating operations are all handled in a totally database agnostic way by NHibernate under the hood thanks to the mapping generated via Fluent NHibernate.
So the end result of this process is that using T4 templates we are able to generate the POCO (Plain Old C# Objects) model files, the Fluent Mapping files, the Derived Repository definitions and the generated portion of the Store all automatically. In addition, we make all classes partial enabling developers to extend them as they see fit. This gives us a tremendous about of flexibility for developers to customize certain operations. This model for repository is a little more closer to what the pattern fully intends, though really is more of a Store pattern, similar to what Linq to SQL and Linq to Entities appear to use to great effect. In coming tutorials I will back track and help you understand how to create a fully functional Repository Store support framework.