NHibernate Event Listener Registration With Fluent NHibernate

I’m a huge fan of NHibernate. It has excellent documentation and just makes the whole job of getting things into and out of the database much more enjoyable.  There is a whole series of posts on NHibernate from one of the committers, Ayende.  When Fluent NHibernate (FNH) came out, it was like butter on sliced bread.  FNH makes it even easier to use NHibernate.

Ayende had a post a while back on how to use Event Listeners.  That helped me to get to event listeners set up.

Event Listeners

namespace somethingimportant.we.hope.infrastructure.app.auditing
{
    using System;
    using System.Security.Principal;
    using System.Web;
    using domain;
    using NHibernate.Event;
    using NHibernate.Persister.Entity;
 
    public class AuditEventListener : IPreInsertEventListener, IPreUpdateEventListener
    {
        public string get_identity()
        {
            string identity_of_updater = WindowsIdentity.GetCurrent().Name;
 
        if (HttpContext.Current != null)
            {
                try
                {
                    identity_of_updater = HttpContext.Current.User.Identity.Name;
                }
                catch
                {
                    //move on
                }
            }
 
            return identity_of_updater;
        }
 
        //http://ayende.com/Blog/archive/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.aspx
        public bool OnPreInsert(PreInsertEvent eventItem)
        {
            Auditable audit = eventItem.Entity as Auditable;
            if (audit == null)
            {
                return false;
            }
 
            DateTime? entered_date = DateTime.Now;
            DateTime? modified_date = DateTime.Now;
            string identity_of_updater = get_identity();
 
            store(eventItem.Persister, eventItem.State, "entered_date", entered_date);
            store(eventItem.Persister, eventItem.State, "modified_date", modified_date);
            store(eventItem.Persister, eventItem.State, "updating_user", identity_of_updater);
            audit.entered_date = entered_date;
            audit.modified_date = modified_date;
            audit.updating_user = identity_of_updater;
 
            return false;
        }
 
        public bool OnPreUpdate(PreUpdateEvent eventItem)
        {
            Auditable audit = eventItem.Entity as Auditable;
            if (audit == null)
            {
                return false;
            }
 
            DateTime? modified_date = DateTime.Now;
            string identity_of_updater = get_identity();
 
            store(eventItem.Persister, eventItem.State, "modified_date", modified_date);
            store(eventItem.Persister, eventItem.State, "updating_user", identity_of_updater);
            audit.modified_date = modified_date;
            audit.updating_user = identity_of_updater;
 
            //insert auditing object here
 
            return false;
        }
 
        public void store(IEntityPersister persister, object[] state, string property_name, object value)
        {
            int index = Array.IndexOf(persister.PropertyNames, property_name);
            if (index == -1)
            {
                return;
            }
            state[index] = value;
        }
    }
}
Great! But now I need to register my event listeners.So I go searching some on the interwebs. And I come across this. Ayende talks about how to registration in the configuration file in a later post, but with FNH, I register in code.  Hmmm… back to the interwebs…
Then I came across Adam Aldrich’s post on how to register the listeners in code. This is from his post on registration:
NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
cfg.EventListeners.PreUpdateEventListeners = 
    new IPreUpdateEventListener[] {new AuditEventListener()};
cfg.EventListeners.PreInsertEventListeners =
    new IPreInsertEventListener[] { new AuditEventListener() };
_sessionFactory = cfg.BuildSessionFactory();
Just what I was looking for! Code registration. But how do I use FNH to set that up?  That’s where some nice detective work and a fluent interface come in.
Fluent NHibernate Registration of Event Listeners
private void build_factory()
{
    if (nhibernate_session_factory == null)
    {
        nhibernate_session_factory = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2005
                .ConnectionString(c => 
                    c.FromConnectionStringWithKey("db")))
            .Mappings(m => 
                m.FluentMappings.AddFromAssemblyOf<VideoMapping>())
            .ExposeConfiguration(cfg => {
                        cfg.EventListeners.PreInsertEventListeners = 
                            new IPreInsertEventListener[] {new AuditEventListener()};
                        cfg.EventListeners.PreUpdateEventListeners = 
                            new IPreUpdateEventListener[] {new AuditEventListener()};
                        })
            .BuildSessionFactory();
    }
}

 

This same thing can be accomplished with VB.NET by making a call to a method (I’ve done that as well). With it’s discoverability, FNH makes it so easy to figure things out sometimes. :D

 

 

kick it on DotNetKicks.com Shout it

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati