Today I encountered a pretty basic scenario that Unity can’t support out of the box: one NHibernate ISession per HttpContext.
The problem is that ISessions are provided by a factory method NHibernateHelper.OpenSession(), and I need to store them in a custom HttpContextLifetimeManager. Unity won’t let me use the two together because no RegisterFactory() overload allows you to specify a LifetimeManager.
Rupert Benbrook has posted a solution to this problem that overrides part of the Unity build-up pipeline (and even goes as far as emitting op codes directly). For simple applications, however, a plain extension method might suffice:
public static IStaticFactoryConfiguration RegisterFactory<T>(
this StaticFactoryExtension extension,
FactoryDelegate factoryMethod, LifetimeManager lifetimeManager)
{
FactoryDelegate wrappedFactoryMethod = delegate
{
LifetimeManager manager = lifetimeManager;
FactoryDelegate method = factoryMethod;
IUnityContainer container = extension.Container;
object o = manager.GetValue();
if (o == null)
{
o = factoryMethod(container);
manager.SetValue(o);
}
return o;
};
return extension.RegisterFactory<T>(wrappedFactoryMethod);
}
This simply wraps the real factory method in a closure that checks a LifetimeFactory first. I can then do:
container.Configure<StaticFactoryExtension>()
.RegisterFactory<ISession>((c) => NHibernateHelper.OpenSession(),
new HttpContextLifetimeManager<ISession>());
This seems to work pretty well.
May 26, 2009



1 Comment
ilker on March 31, 2010 at 2:33 pm.
Hi
I needed same thing and tried as follows and it works.
We only need “.RegisterType(new UnityPerWebRequestLifetimeManager())” additon before configuration to use type with specified life time manager.
So I thing there is no need any extra work except adding StaticFactoryExtension
Or not ?
container.AddNewExtension();
container
.RegisterType(new UnityPerWebRequestLifetimeManager())
.Configure()
.RegisterFactory(
new FactoryDelegate(c => Data.NHibernate.NHibernateHelper.OpenSession()));