Workaround for combining a factory method and Lifetime Manager with Unity

Spread the love

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.