WcfNHibernate is a framework that simplifies the creation and persistence of NHibernate ISession objects when using WCF as well as the underlying data access repository classes that use the NHibernate ISession object.
EditSample
EditAttributing the Service (.svc)
To indicate to Wcf that you would like a new ISession created and associated with each call to an OperationContract a couple of attributes need to be added to the ServiceContract.
First you will need to add a ServiceBahavior attribute that sets the InstanceContextMode to PerCall. This is what forces the creation of call-by-call capabilities in Wcf.
The second attribute is one from this framework called NHibernateContext. This is how you tell the ServiceContract to do the creation and association of the ISession object for each call.
It is *not* possible to run a ServiceContract with the NHibernateContext attribute and not having the InstanceContextMode set to PerCall. Remember that the default InstanceContextMode is PerSession not PerCall so this will need to be explicitly set.
[ServiceContract]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public interface ICustomerServices
{
[OperationContract]
IEnumerable<CustomerListingDto> RetrieveListingOfAll();
}
[NHibernateContext]
public class CustomerServices
{
...
}
EditInitializing NHibernate
While the NHibernateContextAttribute identifies the ServiceContracts that should be using discreet ISession objects on each call, you will also need to create an NHibernate SessionFactory for the sessions to be loaded from. Because SessionFactories are expensive to create you should be doing this once for the life of your application. In a web app, the most common place to do this is in global.asax in the Application_Start method. There are two ways to initialize the SessionFactory for this framework.
The first is to simply call the NHibernateFactory's Initialize method. This will grab the hibernate.cfg.xml file that is in the same directory as the IglooCoder.Commons.dll and use it for configuration of the SessionFactory.
protected void Application_Start(object sender, EventArgs e)
{
NHibernateFactory.Initialize();
}
The second way to initialize the SessionFactory is to use the NHibernate Configuration object. This allows you to point at a hibernate.cfg.xml file that is in specific file path location.
protected void Application_Start(object sender, EventArgs e)
{
NHibernateFactory.Initialize(new Configuration().Configure().BuildSessionFactory());
}
EditUsing the Repository Base Class
There is a repository base class (BaseNHibernateRepository) available to you in the framework. All you need to do is inherit from it on your repository classes and the following functionality becomes available to you:
• < T> FetchById(long id)
• IQueryable< T> FetchAll()
• void SaveOrUpdate(T classToUpdate)
• void Delete (T classToUpdate)
By definition of the base class the type T must be defined by the inheritor and T must be of type IDomain. This is to ensure that the type being pushed or pulled through the repository has an Id field on it. As a result, the Customer class in the example below must implement IDomain for it to work.
A simple implementation of a repository would look like:
public class CustomerRepository : BaseNHibernateRepository<Customer>
{
public CustomerRepository(ISessionStorage sessionStorage):base(sessionStorage)
{}
}
In this example you will want to be using an Inversion of Control framework to be loading the CustomerRepository and injecting in the concrete implementation of ISessionStorage. To do this correctly, your IoC container needs to be configured to return IglooCoder.Commons.WcfNhibernate.WcfSessionStorage when an ISessionStorage type object is required.
EditRolling back failed transactions
The trunk of IglooCommons now contains an automatic rollback capability. By default, rollbacks are expected to be handled manually. The way to do that is as follows:
NHibernateContext.Current.Rollback();
Automatic rollbacks can be configured by adding a parameter to the NHibernateContext attribute that you use to decorate a WCF service.
[NHibernateContext(Rollback.Automatically)]