Blog Stats
  • Posts - 18
  • Articles - 0
  • Comments - 20
  • Trackbacks - 79

 

Wednesday, February 15, 2006

Generic DAO with NHibernate

4/28/06 Update: The NHibernate codeproject.com article wins ASP.NET article of the month. Woohoo!

3/14/06 Update: See how this is used in a sample application at http://www.codeproject.com/useritems/NHibernateBestPractices.asp.

 


 

Hibernate.org has a great article on creating a generic DAO for Hibernate in Java. Below is what I use for the C# port.

 

The interface for common CRUD functionality...

 

public interface GenericDAO {

T GetById(IdDataType id, bool shouldLock);

List GetAll();

List GetByExample(T exampleInstance, string[] propertiesToExclude);

T SaveOrUpdate(T entity);

void Delete(T entity);

}

 

The generic DAO implementation...

 

public abstract class GenericNHibernateDAO : GenericDAO

{

/// Could be set using contruction injection IoC

public GenericNHibernateDAO(ISessionManager sessionManager) {

this.sessionManager = sessionManager;

}

 

public T GetById(IdDataType id, bool shouldLock) {

ISession session = GetSession();

T entity;

 

if (shouldLock) {

entity = (T) session.Load(persitentType, id, LockMode.Upgrade);

}

else {

entity = (T) session.Load(persitentType, id);

}

 

return entity;

}

 

public List GetAll() {

return GetByCriteria();

}

 

protected List GetByCriteria(params ICriterion[] criterion) {

ISession session = GetSession();

ICriteria criteria = session.CreateCriteria(persitentType);

foreach (ICriterion criterium in criterion) {

criteria.Add(criterium);

}

GenericUtils genericUtils = new GenericUtils();

return genericUtils.ConvertToGenericList(criteria.List());

}

 

public List GetByExample(T exampleInstance, string[] propertiesToExclude) {

ISession session = GetSession();

ICriteria criteria = session.CreateCriteria(persitentType);

Example example = Example.Create(exampleInstance);

 

foreach (string propertyToExclude in propertiesToExclude) {

example.ExcludeProperty(propertyToExclude);

}

 

criteria.Add(example);

 

GenericUtils genericUtils = new GenericUtils();

return genericUtils.ConvertToGenericList(criteria.List());

}

 

public T SaveOrUpdate(T entity) {

ISession session = GetSession();

session.SaveOrUpdate(entity);

 

return entity;

}

 

public void Delete(T entity) {

ISession session = GetSession();

session.Delete(entity);

}

 

private ISession GetSession() {

Check.Require(sessionManager != null, "sessionManager was not set");

return sessionManager.OpenSession();

}

 

private Type persitentType = typeof(T);

private ISessionManager sessionManager;

}

 

And for using this within your code...

 

public class ProjectDAONHibernate : GenericNHibernateDAO<Project, int> {

public ProjectDAONHibernate(ISessionManager sessionManager) : base(sessionManager) {}

}

 



Notes:

NHibernate Generics: To use generics with NHibernate, use the “NHibernate Generics” assembly available at http://www.ayende.com/projects/nhibernate-query-analyzer/generics.aspx.

SessionManager: To help with NHibernate session management, a good tool of choice is Castle Project's NHibernate facility:  http://www.castleproject.org/index.php/Facility:NHibernate.  Alternatively, a good design is explained in Chapter 8 of Hibernate In Action by Christian Bauer and Gavin King.  (They should be having a second edition coming out soon.)  The beneift of using Castle Project comes to light when used in conjunction with their Transaction factility; the Transaction facility allows you to mark which actions should be transactional via inline attributes.

Design by Contract:  You may have noticed Check.Require reference.  This is a completely optional, design-by-contract constraint using the VERY light weight framework described at http://www.codeproject.com/csharp/designbycontract.asp.

I've had wonderful success with NHibernate in the past and can continue to embrace it with C# 2.0 using generics.  The .NET community is finally starting to take notice of ORM tools like NHibernate which are helping to shave weeks, if not months, off of development.  I hope you all experience similar successes.

 

 

Copyright © Billy McCafferty