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";
<span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> IDomainContext domainContext;
<span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> ISystemClock clock;

<span style="color: #0000ff">public</span> TimestampInterceptor(IDomainContext domainContext, ISystemClock clock)
{
    <span style="color: #0000ff">this</span>.domainContext = domainContext;
    <span style="color: #0000ff">this</span>.clock = clock;
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">bool</span> OnSave(<span style="color: #0000ff">object</span> entity, <span style="color: #0000ff">object</span> id, <span style="color: #0000ff">object</span>[] state, 
    <span style="color: #0000ff">string</span>[] propertyNames, IType[] types)
{
    var timestampable = entity <span style="color: #0000ff">as</span> ITimestampable;

    <span style="color: #0000ff">if</span>(timestampable == <span style="color: #0000ff">null</span>)
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>;

    var timestamp = GetTimestamp(state, propertyNames);

    timestamp.CreatedDateTime = clock.Now();

    <span style="color: #0000ff">if</span> (domainContext.DomainUser != <span style="color: #0000ff">null</span>)
        timestamp.CreatedByStaff = domainContext.DomainUser.StaffName;

    <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span>;
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">bool</span> OnFlushDirty(<span style="color: #0000ff">object</span> entity, <span style="color: #0000ff">object</span> id, <span style="color: #0000ff">object</span>[] currentState, 
    <span style="color: #0000ff">object</span>[] previousState, <span style="color: #0000ff">string</span>[] propertyNames, IType[] types)
{
    var timestampable = entity <span style="color: #0000ff">as</span> ITimestampable;

    <span style="color: #0000ff">if</span> (timestampable == <span style="color: #0000ff">null</span>)
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>;

    var timestamp = GetTimestamp(currentState, propertyNames);

    timestamp.UpdatedDateTime = clock.Now();

    <span style="color: #0000ff">if</span>(domainContext.DomainUser != <span style="color: #0000ff">null</span>)
        timestamp.UpdatedByStaff = domainContext.DomainUser.StaffName;

    <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span>;
}

<span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> Timestamp GetTimestamp(<span style="color: #0000ff">object</span>[] state, <span style="color: #0000ff">string</span>[] propertyNames)
{
    var timestamp = state[Array.IndexOf(propertyNames, TIMESTAMP_PROPERTY)] <span style="color: #0000ff">as</span> Timestamp;

    <span style="color: #0000ff">if</span>( timestamp == <span style="color: #0000ff">null</span> )
    {
        timestamp = <span style="color: #0000ff">new</span> Timestamp();
        state[Array.IndexOf(propertyNames, TIMESTAMP_PROPERTY)] = timestamp;
    }

    <span style="color: #0000ff">return</span> timestamp;
}

}

 
I haven’t run this through the ringers yet, so let me know if you spot some problems.
Technorati Tags: ,
← A Simple Closure To Handle Try/Catch Around Transactions
Influence Change →