17

I want to add an event listener (IPreUpdateEventListener) to add NHibernate but I can't seem to find an example when using a fluent configuration.

I want to be able to add the listener when I create the session factory, e.g. when the following code is execute.

_sessionFactory = Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2005.ConnectionString(connectionString).ShowSql())
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<IEntity>())
    .BuildSessionFactory();

Anyone know how to do this?

AwkwardCoder
  • 24,893
  • 27
  • 82
  • 152

3 Answers3

34

So, late response, but for the sake of posterity, to add listeners without removing existing registration listeners (like the earlier answer from Bengt Be will do):

var config = new Configuration ();
config.AppendListeners (ListenerType.PreUpdate, new [] { new AuditEventListener () });

etc.

Matt Enright
  • 7,245
  • 4
  • 33
  • 32
  • This worked for me, except it ended up appending the listener twice. Must be something wrong with my config. Setting instead of appending worked in that it only called the OnPreUpdate method once. – shanabus Dec 18 '13 at 20:14
13

Late answer, found your question when I was trying to do the same. Found a solution that should work:

_sessionFactory = Fluently.Configure()
   .Database(MsSqlConfiguration.MsSql2005.ConnectionString(connectionString).ShowSql())
   .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Entity>())
   .ExposeConfiguration(c => c.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] {new AuditEventListener()});
BengtBe
  • 4,465
  • 1
  • 26
  • 19
  • 3
    Be very careful with that code. You are actually removing the existing event listeners instead of just adding your own to the list. I just discovered that if I try use the optimistic locking in FluentNH (using the Version mapping), it will not work because it automatically registers some event listeners on its own and the code you provided removes them. – Igor Brejc Feb 15 '11 at 16:11
  • 1
    OK, a correction: I was overriding the wrong listeners for auditing. But still my question remains: is it wise to assume you can remove any existing listeners when calling ExposeConfiguration? – Igor Brejc Feb 15 '11 at 16:43
6

Resurrecting the dead here but this:

........
   .ExposeConfiguration(c => c.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] {new AuditEventListener()});

Should be:

.ExposeConfiguration(c => c.AppendListeners(ListenerType.PreUpdate, new object[]
    {
        new AuditEventListener()
    });

I believe the 'SetListener' method (described in another answer) would also remove all previous listeners.

If you are into something a little more dynamic, you could do this:

private void AddListenerToConfiguration<T>(FluentConfiguration config, params ListenerType[] typesForListener)
        where T : class
    {
        var listener = Activator.CreateInstance<T>();

        config.ExposeConfiguration(x =>
            {
                foreach (var listenerType in typesForListener)
                {
                    x.AppendListeners(listenerType, new T[]
                    {
                        listener
                    });
                }
            });
    }

And then call something like this:

AddListenerToConfiguration<AuditEventListener>(smFactory, 
            ListenerType.PreUpdate);

This allows for cleaner code while you are looking at the Fluent configuration. It also allows you to easily register a single type to multiple listener types.

As for removing the default listeners, I wouldn't remove them unless I have a listener that inherits from the default listener implementation and calls base.METHODNAME on the overridden methods or replicates the same behavior as that of the default listeners.

docmanhattan
  • 2,368
  • 1
  • 25
  • 28