NHibernate interceptor magic tricks, the example

Below, you can find the final example of working interceptor, which uses some methods described in text of the last few blog entries (1, 2, 3, 4 and 5). Scan the example and go below to get some explanation about it!

public class ExampleInterceptor : EmptyInterceptor
{
	private const int MaxStatements = 50;
	private static readonly ILog Logger = LogManager.GetLogger(typeof(UpdateInterceptor));

	private readonly InterfaceFinder _interfaceFinder;
	private readonly IUnityContainer _container;
	private ISession _session;

	private int _statementCount;

	public UpdateInterceptor(IUnityContainer container, InterfaceFinder interfaceFinder)
	{
		_container = container;
		_interfaceFinder = interfaceFinder;
	}

	public override void PostFlush(ICollection entities)
	{
		if (_session.Transaction == null)
		{
			throw new InvalidOperationException("Use transactions!");
		}
		base.PostFlush(entities);
	}

	public override void SetSession(ISession session)
	{
		base.SetSession(session);
		_session = session;
	}

	public override string GetEntityName(object entity)
	{
		if (entity == null)
		{
			return null;
		}

		var interfaceType = _interfaceFinder.GetDeepestInterface(entity);

		if (interfaceType == null)
		{
			return null;
		}

		return interfaceType.FullName;
	}

	public override SqlString OnPrepareStatement(SqlString sql)
	{
		if (_statementCount++ == MaxStatements)
		{
			Logger.WarnFormat("Max number of statements exceeded");
		}

		return base.OnPrepareStatement(sql);
	}

	public override object Instantiate(string clazz, EntityMode entityMode, object id)
	{
		if (entityMode == EntityMode.Poco)
		{
			var sessionFactory = _session.SessionFactory;
			var metadata = sessionFactory.GetAllClassMetadata()[clazz];
			var type = metadata.GetMappedClass(entityMode);

			if (type != null)
			{
				var instance = _container.Resolve(type);
				var classMetadata = sessionFactory.GetClassMetadata(clazz);

				classMetadata.SetIdentifier(instance, id, entityMode);

				return instance;
			}
		}

		return null;
	}
}

The constructor
As you’ve noticed, there is a dependency injection in here! Two arguments are: unity container instance; interface finder, which allows you to use interfaces with their implementation hierarchies. About the second, you can read here and here.

Post flush
does nothing more than ensuring that you’re running it in a transaction. Yep, one for all, all for one!

SetSession
remembers the session instance in a field.

GetEntityName
implementation indicates that there are some interfaces mapped, for instance IA and IB : IA. It allows the most nested interface to be easily find for the object type.

OnPrepareStatement
preserves a sane number of statements per session (hence, per request, because session per request scenario is considered).

Instantiate
is the final method. It uses the passed container to create an instance of the passed class. Having interfaces mapped, it’s must have since you cannot call new for interface :P

Unity registration
Having this interceptor we need a nice and easy way of registering any interceptor (which type is hold in _interceptorType field) in the container. That’s performed by the following unity extension:

public class NhUnityContainerExtension : UnityContainerExtension
{
	protected override void Initialize()
	{
		// ...
		// save configuration to container for any later use
		Context.Container.RegisterInstanceWithSingletonLifetimeManager(cfg);

		// build factory and register interceptor
		var factory = cfg.BuildSessionFactory();
		Context.Container.RegisterInstanceWithSingletonLifetimeManager(factory);
		Context.Container.RegisterTypeWithPerRequestLifetimeManager(typeof(IInterceptor), _interceptorType);

		var key =  NamedTypeBuildKey.Make<ISession>();
		// setup nhibernate session build plan policy
		Context.
			Policies.
			Set<IBuildPlanPolicy>(
				new DelegateBuildPlanPolicy(
					ctx =>
							{
								// create interceptor already registered
								var interceptor = BuilderContext.NewBuildUp<IInterceptor>(ctx);
								var buildUpFactory =
									BuilderContext.NewBuildUp<ISessionFactory>(ctx);
								return buildUpFactory.OpenSession(interceptor);
							}),
				key);

		// setup lifetime policy
		Context.
			Policies.
			Set<ILifetimePolicy>(CreatePerRequestLifeTimeManager(), key);
	}
		
	private LifetimeManager CreatePerRequestLifeTimeManager()
	{
		// ...
	}
}

If you know the architecture of Unity, this extension is pretty safe explanatory, event mine extension methods.

That’s the end of Interceptor journey. Happy Intercepting!

You don’t mess with Unity’s policies

Recently I ran into a problem. Quite well designed system degraded in terms of performance after a few commits. The whole architecture is wired with an infrastructure library written with unity container as a base for dependency injection. One of its features is a simple adding proxies, for instance adding some information to an exception’s data in case of throwing one. The interceptor doing it is quite simple:

public class ExceptionDataAppendingInterceptor : IInterceptor
{
	public void Intercept(IInvocation invocation)
	{
		try
		{
			invocation.Proceed();
		}
		catch (Exception ex)
		{
			ex.AppendMethodCallData(
			    invocation.Method, invocation.Arguments);
			throw;
		}
	}
}

The exension method appending data is a bit more complex but does not add any value to the post.

Having in mind that exception can be thrown at various points of an application and having it run for the very first time in the test environment, I configured unity to set proxy to the majority of created objects, which are resolved as interfaces (proxifing their interfaces).
When I run a profiled, it showed a major overhead created by one strategy, being responsible for wrapping a created object with use of DynamicProxy2. What the profiler shown was plenty of calls to IEnumerable extensions method. The strategy called one policy which before fixing looked like this:

public class InterceptorSelectorPolicy : IBuilderPolicy
{
	private readonly IDictionary<Type, List<Func<IBuilderContext, IInterceptor>>> 
		_activators;
	private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();

	public InterceptorSelectorPolicy(
		IDictionary<Type, List<Func<IBuilderContext, IInterceptor>>> activators)
	{
		_activators = activators;
	}

	/// <summary>
	/// Determines whether the specified context is applicable for proxy generation.
	/// </summary>
	public bool IsApplicable(IBuilderContext context)
	{
		return _activators.ContainsKey(BuildKey.GetType(context.OriginalBuildKey));
	}

	/// <summary>
	/// Creates the proxy using <see cref="IBuilderContext.Existing"/> as target
	/// and <see cref="IBuilderContext.OriginalBuildKey"/> as proxied interface type.
	/// </summary>
	public object CreateProxy(IBuilderContext context)
	{
		var typeToProxy = BuildKey.GetType(context.OriginalBuildKey);

		return ProxyGenerator.CreateInterfaceProxyWithTarget(
			typeToProxy,
			context.Existing,
			_activators[typeToProxy]
			.Select(a => a(context))
			.ToArray());
	}
}

It’s worth to mentioned that it was called every time an object was created… After refactorization the code lost all the enumerable _create_state_machine_for_my_iterator_ stuff and was changed to:

public class InterceptorSelectorPolicy : IBuilderPolicy
{
	private readonly Type _typeToProxy;
	private readonly Func<IBuilderContext, IInterceptor>[] _activators;
	private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();

	public InterceptorSelectorPolicy(Type typeToProxy, 
		Func<IBuilderContext, IInterceptor>[] activators)
	{
		_typeToProxy = typeToProxy;
		_activators = activators;
	}

	/// <summary>
	/// Gets a value indicating whether this proxified should be applied.
	/// </summary>
	/// <value>
	///     <c>True</c> if this instance is applicable; otherwise, <c>false</c>.
	/// </value>
	public bool IsApplicable
	{
		get { return _activators != null && _activators.Length > 0; }
	}

	/// <summary>
	/// Creates the proxy using <see cref="IBuilderContext.Existing"/> as target
	/// and <see cref="IBuilderContext.OriginalBuildKey"/> as proxied interface type.
	/// </summary>
	/// <param name="context">The context.</param>
	/// <returns>Returns created proxy.</returns>
	public object CreateProxy(IBuilderContext context)
	{
		return ProxyGenerator.CreateInterfaceProxyWithTarget(
			_typeToProxy,
			context.Existing,
			CreateInterceptors(context));
	}

	private IInterceptor[] CreateInterceptors(IBuilderContext context)
	{
		var result = new IInterceptor[_activators.Length];
		for (var i = 0; i < _activators.Length; i++)
		{
			result[i] = _activators[i](context);
		}
		return result;
	}
}

No dictionary look ups, no iterators, no needed overhead. The whole idea was simplified and now, for an object having no need of proxifing it is reduced to a simple, nolock _is_null_ array check called by a post build strategy. You don’t mess with Unity’s policies unless you have a nice stress test written.