Creating a Timestamp Interceptor in NHibernate

In a previous post, I gave an example of a Timestamp class and how one might create an ICompositeUserType to map it within NHibernate. Here I want to show of an example of an IInterceptor which will automatically populate the values for my Timestamp class. OnSave is for the inserts, and OnFlushDirty is for the updates. There are a bunch of other methods that you can tap into for different things, so check out the NHibernate docs.
 
public class TimestampInterceptor : EmptyInterceptor
{
    private const string TIMESTAMP_PROPERTY = "Timestamp";

    private readonly IDomainContext domainContext;
    private readonly ISystemClock clock;

    public TimestampInterceptor(IDomainContext domainContext, ISystemClock clock)
    {
        this.domainContext = domainContext;
        this.clock = clock;
    }

    public override bool OnSave(object entity, object id, object[] state, 
        string[] propertyNames, IType[] types)
    {
        var timestampable = entity as ITimestampable;

        if(timestampable == null)
            return false;

        var timestamp = GetTimestamp(state, propertyNames);

        timestamp.CreatedDateTime = clock.Now();

        if (domainContext.DomainUser != null)
            timestamp.CreatedByStaff = domainContext.DomainUser.StaffName;

        return true;
    }

    public override bool OnFlushDirty(object entity, object id, object[] currentState, 
        object[] previousState, string[] propertyNames, IType[] types)
    {
        var timestampable = entity as ITimestampable;

        if (timestampable == null)
            return false;

        var timestamp = GetTimestamp(currentState, propertyNames);

        timestamp.UpdatedDateTime = clock.Now();

        if(domainContext.DomainUser != null)
            timestamp.UpdatedByStaff = domainContext.DomainUser.StaffName;

        return true;
    }

    private static Timestamp GetTimestamp(object[] state, string[] propertyNames)
    {
        var timestamp = state[Array.IndexOf(propertyNames, TIMESTAMP_PROPERTY)] as Timestamp;

        if( timestamp == null )
        {
            timestamp = new Timestamp();
            state[Array.IndexOf(propertyNames, TIMESTAMP_PROPERTY)] = timestamp;
        }

        return timestamp;
    }
}
 
I haven’t run this through the ringers yet, so let me know if you spot some problems.
Technorati Tags: ,

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Ray Houston

Ray is a software development leader and architect with 20 years hands-on experience. He enjoys finding elegant solutions to complex problems and delivering real value to customers. Ray is a speaker and contributor to community events.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

3 Responses to Creating a Timestamp Interceptor in NHibernate

  1. Ray, I have been battleing tirelessly trying to get this example working with my castle/nhibernate/rhino-tools (binsor) setup.

    I can get the interceptor to fire then it spews with a IInterceptor not implemented error.

    Correct me if im wrong, but EmptyInterceptor implements IInterceptor – very confusing.

    Have you got this running with binsor, registering the Interceptor as a component in the boo file?

    Any advice would be great!

    David

  2. Got it sorted!

    Was mixing IInterceptor’s between Castle and NHIbernate – whoops!

    David

  3. Marcus says:

    Hi, very nice example, works great for simple values, but when I try to modify a collection in the currentState it doesn’t work because “NHibernate.Collection.Generic.PersistentGenericBag`1cannot be converted to a “System.Collections.Generic.List`1[]”

    Any Ideas?

    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>