Skip to content

Instantly share code, notes, and snippets.

@dvhthomas
Created December 6, 2009 22:44
Show Gist options
  • Save dvhthomas/250479 to your computer and use it in GitHub Desktop.
Save dvhthomas/250479 to your computer and use it in GitHub Desktop.
NHibernate event listener
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NHibernate.Event;
using StructureMap;
namespace *****.Core.Persistence
{
/// <summary>
/// Adds auditing to classes that implement <see cref="IAuditable"/>
/// </summary>
/// <remarks>This is an NHibernate interceptor and will get called
/// automatically whenever a transient entity is persisted
/// (INSERTed) for the first time. It will examine the transient
/// class for any <see cref="AuditedFieldAttribute"/>s on properties
/// to get underlying column names that ***** might need to
/// keep track of in the audit table (<see cref="*****Metadata"/>).</remarks>
public class AuditEventListener : IPostInsertEventListener
{
public const string *****AuditUser = "*****Services";
#region IPostInsertEventListener Members
public void OnPostInsert(PostInsertEvent insertEvent)
{
// Make sure it's auditable first
var audit = insertEvent.Entity as IAuditable;
if (audit == null)
return;
// Then go in to specific implementations, starting with Workorders
var workorder = audit as Workorder;
if (workorder == null)
return;
if (workorder.DomainId.HasValue)
{
CreateAuditTrail(workorder, ObjectNames.TableWorkorder);
}
}
#endregion
/// <summary>
/// Create audit trails for any fields that ***** needs to track. We do this
/// by examining the class for fields with the <see cref="AuditedFieldAttribute"/>
/// on them and then checking which of those fields ***** is interested
/// in tracking.
/// </summary>
private static void CreateAuditTrail<T>(T auditThis, string tablename) where T : IAuditable
{
IList<*****Metadata> audits = new List<*****Metadata>();
var ar = ObjectFactory.GetInstance<IAuditRepository>();
IEnumerable<AuditedItem> auditableFields = ar.AuditableFields((int) auditThis.DomainId, tablename);
if (auditableFields == null || auditableFields.Count() == 0) return;
Type auditableType = typeof (T);
foreach (PropertyInfo propertyInfo in auditableType.GetProperties())
{
// We're only interested in properties
// that are auditable
object[] customAttributes = propertyInfo.GetCustomAttributes(typeof (AuditedFieldAttribute), false);
foreach (object o in customAttributes)
{
var auditedAttribute = o as AuditedFieldAttribute;
object newValue = propertyInfo.GetValue(auditThis, null);
if (auditedAttribute != null)
{
AuditedItem matchingRecord =
auditableFields.FirstOrDefault(af => af.Field == auditedAttribute.DatabaseColumn);
// Looks like we've got an attribute that ***** wants
// to keep track of. Add it to the list...
if (matchingRecord != null)
{
var meta = new *****Metadata
{
ChangedByUser = *****AuditUser,
ModifiedAt = DateTime.UtcNow,
OldValue = null,
NewValue = newValue == null ? null : newValue.ToString(),
SourceField = auditedAttribute.DatabaseColumn,
SourceId = auditThis.UniqueId,
SourceTable = tablename
};
audits.Add(meta);
}
}
}
}
ar.CreateAuditTrail(audits);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment