Dependency Injection with NHibernate and Autofac
Fabio just recently committed changes to NHibernate which centralize all of NHibernate’s Activator.CreateInstance
calls to an IObjectsFactory
instance. This is exciting because this gives us an opportunity to provide dependency injection services to all of those NHibernate-specific infrastructure types (IUserType, etc.).
To give you a concrete example of what I am talking about, check back to Ayende’s EncryptedStringUserType. Rather than getting an instance of ICryptoProvider
via a singleton accessor, it is now possible to have NHibernate inject the ICryptoProvider
dependency through the constructor. This is very valuable in cases where the ICryptoProvider
has other dependencies or has some parameters that need to come from configuration. You get full support from the container for that.
Fabio wrote up a post describing the implementations for Castle and Spring. So, I thought I’d follow suit with an implementation for my new favorite container, Autofac (why it is my new favorite container will be a topic for another post).
To use it, make sure you are using the latest trunk of NHibernate. Then, just add a reference in your project to Autofac.Integration.NHibernate
. At this time, the only way to configure the BytecodeProvider
is programmatically. So, BEFORE you call new NHibernate.Cfg.Configuration().Configure()
, you need to set the BytecodeProvider
to the AutofacBytecodeProvider
.
containerProvider = new ContainerProvider(builder.Build());
Environment.BytecodeProvider = new AutofacBytecodeProvider(
containerProvider.ApplicationContainer, new ProxyFactoryFactory());
Then just enjoy the DI goodness integrated with NHibernate. If any type NHibernate needs is not registered with the container, it will fall back to creating the type with Activator.CreateInstance
.
The code can be found here. I am going to contact the Autofac guys and see about putting this into the Autofac.Contrib project.
This is now included in the Autofac.Contrib project.