Your own NHibernate SessionFactory for Web applications

The beauty of the Castle Windsor container is that it allows you the flexibility to do many things with a relatively small API without having to learn all the many pluggable components out there. In short, sometimes you don’t need to use contribs just because they are available, doing so increases your coupling and in turn reduces your flexibility – abstraction comes at a price. Case in point the NHibernate Facility, this allows you to create a session instance for each web request, the key benefit being that you can use lazy loading on your entities and take full advantage of the unit of work which NHibernate does so well. The point is you don’t need this facility, and I’ll show you how to create the same behaviour without it.

These are the components you need to create:

1. Windsor Container implementation: a wrapper plus configuration.

This will be used for all your dependency injection needs, including supplying NHibernate sessions to services at runtime.  You will notice that I have named the NhibernateSessionOpener - “nhsessionopener”, you can find the component referring to this in the configuration file.

public class Container
{
private static IWindsorContainer _container;
public static IWindsorContainer Instance
{
get
{
if (_container == null)
{
_container = new WindsorContainer(configuration);
_container.Register(Component.For<NhSessionOpener>()
.Named("nhsessionopener"));
}
return _container;
}
}
}

Container Configuration:


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

<facilities>
<facility id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility,
Castle.MicroKernel"
/>
</facilities>

<components>
<component id="nhsessionimpl" lifestyle="PerWebRequest"
type="NHibernate.Impl.SessionImpl, NHibernate"
factoryId="nhsessionopener"
factoryCreate="Open" />

<!-- Other components follow here -->
</components>

</configuration>

2. NHibernate SessionFactory wrapper

You only need one NHibernate SessionFactory which will be accessible from this wrapper instance. 


public class NhibernateSessionFactory
{
private static ISessionFactory instance;

public static ISessionFactory Instance
{
get
{
if (instance == null) instance = create();
return instance;
}
}

private static ISessionFactory create()
{
var cfg = new NHibernate.Cfg.Configuration();
cfg.AddAssembly(Assembly.GetAssembly(typeof(MyAssembly)));
return cfg.BuildSessionFactory();
}
}

3. A regular Factory class to return Nhibernate sessions.

public class NhibernateSessionOpener
{
public static ISession Open()
{
return NhibernateSessionFactory.Instance.OpenSession();
}
}

The delegation pipeline

This diagram demonstrates how it all fits together:

pipeline



Programmatic usage:

var session = Container.Instance.Resolve<SessionImpl>();


Configuration for constructor or setter injection:

<component id="myComponent" type="MyAssembly.MyNamespace.MyComponent, 
MyAssembly.MyNamespace"
>
<parameters>
<Session>${nhsessionopener}</Session>
</parameters>
</component>


So to wrap up, whilst you do need to do a little work setting this up this is really only the addition of two small classes, the benefit of course is that you have more flexibility and are not hampered by unnecessary abstraction.

Unleashing Attributes with Dynamic Proxy

A flexible way of hooking into attributes is by using a factory method to generate proxies of your entities. In my example I’m going to create a proxy using Dynamic Proxy and then write the name of the method called plus the exact time in milliseconds to the output screen in Visual Studio. The benefit of this is that this functionality does not dirty my entities with non-core detail and makes it easy to apply the functionality in a declarative style.

The Desired Result
By running the following code we can track the exact time between method calls to proxied instances of the class. This gives us a lightweight debugging performance monitor for our application.

[Test]
public void should_print_time_and_message_of_proxy_member_call()
{
var dummy = ProxyFactory.Create<Dummy>();
dummy.Method1();
Thread.Sleep(100);
dummy.Method2();
}

the output from the console should look like this:
Dummy instance accessed. @ 00:38:34.8752500875
Method1 Executed.
Dummy instance accessed. @ 00:38:34.9846250984
Method2 Executed.

The Dummy Class
As you can see the attribute has been applied to our ‘Dummy Class’ with a general message.
[TimeLog("Dummy instance accessed.")]
public class Dummy
{

public virtual void Method1()
{
Debug.WriteLine("Method1 Executed.");
}

public virtual void Method2()
{
Debug.WriteLine("Method2 Executed.");
}
}


Defining the Attribute

public sealed class TimeLoggerAttribute : Attribute
{
private readonly string _message;

public TimeLoggerAttribute(string message)
{
_message = message;
}
}


As you can see our attribute simply allows us to add a message to a type member’s metadata.

Creating the Proxy factory
The proxy factory creates a class proxy of the type passed into it as a type parameter, in our example above it is a class called ‘Dummy’. Note, that in order to create a proxy which is capable of being intercepted you must make the members virtual to allow the proxy to override the implementation of each member:

public class ProxyFactory
{
private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();

public static T Create<T>()
{
return (T)Create(typeof(T));
}

public static object Create(Type type)
{
var proxy = ProxyGenerator.CreateClassProxy(
type, new IInterceptor[] { new TimeLogInterceptor() });
return proxy;
}
}


public class TimeLogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var type = invocation.Proxy.GetType().BaseType;
var attributes = type.GetCustomAttributes(typeof(TimeLogAttribute), false);
var attribute = attributes.FirstOrDefault() as TimeLogAttribute;
if (attribute != null)
{
Debug.WriteLine(string.Format("{0} @ {1}{2}",
attribute.Message, DateTime.Now.TimeOfDay, DateTime.Now.Millisecond));
}
invocation.Proceed();
}
}

The TimeLogInterceptor is doing the real work here, whilst the example given is somewhat fictional, by using attributes and proxies it opens up opportunities for aspect-oriented style programming you may not have attempted before.

Links:
Excellent Multipart Tutorial about Dynamic Proxy by Krzysztof Koźmic.
Castle Project Dynamic Proxy.