;

Persistence Ignorant POCOS part 3 – NHibernate

Posted : Friday, 18 March 2011 15:07:29

In this, the third post in a series comparing the developer experience of hooking up a POCO using various ORMs I shall be creating an NHibernate implementation of the application. NHibernate is an open source project, it is a port to .Net from the highly popular JAVA persistence tool Hibernate. In order to speed things up a bit (as well as making life about a million % easier) I will be using fluent NHibernate which allows for a config-file free configuration of NHibernate (under the covers it does exactly the same but you don’t need to write masses of xml).

This first step in creating the NHibernate ‘flavour’ of the persistence layer was to add a new class library to the application called LcaModel.NHibernate. To this class library project I added an implementation of each of the repositories and a class to handle the wiring up of the dependencies. The project structure now looked like this:

poco3-solution

I also had to add a few references to the project that NHibernate requires – I wont list all of these but they are contained in the _Assemblies folder of the accompanying download.

As you can see the naming convention is pretty straightforward. The implementation of each of the repositories was created using the Visual Studio ‘implement interface’ context menu functionality so all methods would throw a NotImplementedException if invoked. The NHibernateModule class shown above simply tells Ninject to use the NHibernate implementations of each of the repositories (see part 1 for a refresher of how the DI part of the application works). In order to actually use this new implementation I simply altered the command line parameter of the LightsCameraAuction project to “NHibernate” and hit ‘F5’. As soon as the application launched an exception was thrown, not the NotImplementedException I was expecting though. I altered the error handler in the Main method of the LightsCameraAuction.Program class to feedback the error test to the console window and ran it again, this is what I got:

referencebug

Its fairly clear what’s causing the error but it took me a while to solve the problem. What was a little odd was that the I had added the NHibernate.ByteCode.Castle as a reference to the project but it was not copying to the bin directory. I should also note here that in previous posts I was using a post build event to make sure the persistence assembly (in this case LightsCameraAuction.NHibernate.dll) was located in the bin directory of the LightsCameraAuction project but for this implementation I simply added this NHibernate project as a reference to the LightsCameraAuction project meaning that on building, this assembly (and all its dependencies) would should be copied to where the LightsCameraAuction.exe could find it. The reason that the NHibernate.ByteCode.Castle.dll was not being copied was down to the fact that none of the code in my new project was directly using it. I found this out (and the subsequent fix) thanks to this post. The fix was to add another class to this project, the contents of which are shown below:

    5     internal class ReferenceBug

    6     {

    7         /// <summary>

    8         /// https://forum.hibernate.org/viewtopic.php?f=25&t=1007657&start=0

    9         /// </summary>

   10         static void Fix()

   11         {

   12             Castle.DynamicProxy.DefaultProxyBuilder fix1 = new Castle.DynamicProxy.DefaultProxyBuilder();

   13             ProxyFactoryFactory fix2 = new ProxyFactoryFactory();

   14         }

   15     }

This basically forces visual studio to copy the NHibernate.ByteCode.Castle.dll along with all the other assemblies.

So after adding this fix I ran the project again and this time got the NotImplementedException I was expecting as soon as the AuctionService attempted to add a Bidder to the NHibernateBidderRepository. So the next step was to add the persistence code. Nhibernate operates using an object known as a Session, this is the means by which entities are change-tracked, lazy-loaded and persisted – it works in a similar way as the ObjectContext does in EntityFramework. In order to utilise this Session class, an instanmce needs to be created – this is achieved by means of a factory class known as a SessionFactory which is what contains all of the configuration data required to connect to the database. Given that I would be using the same SessionFactory for this project I created a class class N

  • (This will not appear on the site)