Welcome to SofiaDev.Org's Blogs Sign in | Join | Help

Using nHibernate with .NET Framework 2.0 and a generic data factory implementation.

One of the projects currently I’m working on is using nHibernate as a data persistence framework. If you’re not familiar with the concept, check out Nikola’s article on nHibernate.

 

Ideally we want to write as little as possible code that deals with data access, and be able to stay in control on what’s happening with the data access at the same time, nHibernate is a great tool for doing that. In this post we’ll take a look at the usage of nHibernate with MS .NET 2.0 and especially with the use of generics. I’ve written a simple generic data factory class that does provide everything we’ll need for all of the data access in our application.

 

In addition, I’ve found an interesting behavior while trying to use assigned Id generator within my mapping classes. What is it about? Well – it doesn’t work as you might expect it to. Because of some strange reason (or maybe a bug) – I don’t know. I didn’t have the time to investigate ‘till now, so I’ll leave that for a later post.

 

So what’s the data model, and what do we want to achieve?

 

We’ll start with a single entity – contact’s picture, which has three fields:

-          ID of int

-          ImageType of string

-          And the image itself with is going to be stored in the DB in an image field.

 

The class definition looks like this:

Here we have all of the fields I’ve described already along with a two more – an ID and TableName. Those two are being used in the Search class in my app where I need to be able to generate dynamically SQL statements. They come from a base abstract class, called DataObject.

 

The mapping file (which specifies how nHibernate should do the mapping from the DB into the classes and the other way around looks like this:

 

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="SofiaDev.nHibernate.Data" assembly="nHibernateDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">

  <class name="ContactPicture" table="Images">

    <id column="ImageID" name="ImageID" type="System.Int32">

      <generator class="assigned" />

    </id>

    <property name="Image" column="TheImage" type="System.Byte[]" />

    <property name="ContentType" column="ImageType" type="System.String" />

  </class>

</hibernate-mapping>

 

 

So how do we retrieve and save data from and into the DB? Usually we would either have to define a base class that has a couple of basic Save() and Get() functions and continue recreating it (either inheriting or by the good-old copy/paste technique). Either way it’s something that takes a lotta time and can be excluded from the scope of our project.

 

In nHibernate we use a sort of a session context which hides the underlying connections and everything else we need in order to work with the data. For that reason I’ve defined a single class that takes care of the initialization of nHibernate, called InitializerFromSchema.

My class implements the Singelton pattern by hiding it’s constructor and exposing a single static property called Instance. The getter of the property needs to check if the instance has been initialized and if not, it needs to do that. Then it will return a reference pointing to the instance.

The instance itself holds a single instance of a class implementing NHibernate.ISessionFactory interface. That interface is what the outside world knows about nHibernate. Everything else is meant to be hidden for now.

So here’s the initializer:

 

 

Then we have a generic class – our data factory that deals with the instantiation of the correct typed data access component.

This one is going to be instantiated with a reference to a type, which will be the type we’ll access the data for.

 

A simple instantiation of the factory with our simple ContactPicture class looks like this:

 

DataClassesFactory<ContactPicture> picFactory = new DataClassesFactory<ContactPicture>();

 

try

{

      picFactory.Insert(pic);

}

catch (Exception ex)

{

      Console.WriteLine(ex.Message);

}

 

Where the pic variable is actually an the instance we want to save into the database.

Check out the attachment for the complete solution along with the source code.

Published 18 Април 2006 20:35 by branimir
Attachment(s): ConsoleApplication4.zip

Comments

No Comments

Anonymous comments are disabled