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.