NHibernate interceptor magic tricks, pt. 3

The very last meeting with IInterceptor was ended by description of IInterceptor.GetEntityName(object entity); method. It’s time to step into the kingdom of almighty DI and IoC and learn how to combine it with NHibernate.
Instantiate me, now!
Imagine that you have a dependency passed as your entity constructor. Or you have some methods or properties which should be called immediately after one entity construction. (It’s out of the scope of this blog whether injection dependencies in your entities is good or bad. You can ask Google and check whether one or another solution fits for you.) One of the proposals of having an entity class with a non default constructor is providing a custom IByteCodeProvider. You can find this solution in here but I would recommend another one, if only entity creation bothers you (the mentioned IByteCodeProvider initializes much more NHibernate elements than you can imagine). The second approach is to use IInterceptor.Instantiate(string entityName, EntityMode entityMode, object id) method. As it was shown by Ayende in his MSDN article, the code should look like (I use in the example Unity container interface):

public class DependencyInjectionInterceptor : EmptyInterceptor
{
    private readonly IUnityContainer _container;
    private ISession _session;

    public DependencyInjectionInterceptor (IUnityContainer container)
    {
        _container = container;
    }

    public void SetSession(ISession session)
    {
        _session = session;
    }

    public override object Instantiate(string clazz, EntityMode entityMode, object id) 
    {
        if(entityMode == EntityMode.Poco)
        {
            var type = Type.GetType(clazz);
            if (type != null)
            {
               var instance = _container.Resolve(type);
               var md = _session.SessionFactory.GetClassMetadata(clazz);
               md.SetIdentifier(instance, id, entityMode);
               return instance;
            }
        }
        return base.Instantiate(clazz, entityMode, id);
  }
}

You can consider passing the ISessionFactory in the constructor as dependency, but as I tend to use IInterceptor one per session, I simply use the SetSession method and further, the SessionFactory property.

That would be all about a simple case of dependency injection with NHibernate (creating only your entities). It seems that there will be a few posts more about IInterceptor stuff ;-)

About these ads

4 responses to “NHibernate interceptor magic tricks, pt. 3

  1. I figured out my issue. I needed to register the type with the dependency in my IoC container as well as the dependency itself.

  2. If you just could wait a few days, I would present a full-blown sample of an interceptor implementing all the features I mentioned. It’ll take a while to gather it in one place, but yes – I do have an example because I’m currently using it (the dependency stuff) in a few of my projects :)

  3. Do you happen to have a sample of your implementation of this? I have been looking for something like this for a while but can’t seem to get NHibernate to use the injector to satisfy the POCO’s dependencies.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s