|
using System;
using System.Reflection;
namespace TypeBuilderLib.AOP
{
/// <summary>Group interceptors together and exposes <see cref="IInterceptor"/>.</summary>
/// <remarks>Useful when we want to chain interceptors.</remarks>
public class InterceptorGroup : IInterceptor
{
#region Inner types
private class GroupMethodInvoker : IMethodInvoker
{
private readonly IMethodInvoker realInvoker;
private readonly IInterceptor[] interceptors;
private readonly int currentInterceptorIndex;
/// <summary>Construct a group invoker.</summary>
/// <param name="realInvoker"></param>
/// <param name="interceptors"></param>
/// <param name="currentInterceptorIndex"></param>
public GroupMethodInvoker(
IMethodInvoker realInvoker,
IInterceptor[] interceptors,
int currentInterceptorIndex)
{
this.realInvoker = realInvoker;
this.interceptors = interceptors;
this.currentInterceptorIndex = currentInterceptorIndex;
}
#region IMethodInvoker Members
MethodBase IMethodInvoker.Method
{
get { return realInvoker.Method; }
}
object[] IMethodInvoker.Parameters
{
get { return realInvoker.Parameters; }
}
object IMethodInvoker.Invoke()
{
IMethodInvoker invoker;
if (currentInterceptorIndex + 1 < interceptors.Length)
{
invoker =
new GroupMethodInvoker(realInvoker, interceptors, currentInterceptorIndex + 1);
}
else
{
invoker = realInvoker;
}
return interceptors[currentInterceptorIndex].InterceptCall(invoker);
}
#endregion
}
#endregion
private IInterceptor[] interceptors;
#region IInterceptor Members
object IInterceptor.InterceptCall(IMethodInvoker methodInvoker)
{
IMethodInvoker groupMethodInvoker = new GroupMethodInvoker(methodInvoker, Interceptors, 0);
return groupMethodInvoker.Invoke();
}
#endregion
/// <summary>Exposes a list of interceptor.</summary>
public IInterceptor[] Interceptors
{
get { return interceptors; }
set { interceptors = value; }
}
/// <summary>
/// Returns <see cref="Interceptors"/> or a default implementation if the list is empty.
/// </summary>
protected IInterceptor[] NonEmptyInterceptors
{
get
{
if (Interceptors == null || Interceptors.Length == 0)
{
return new IInterceptor[] { new DefaultInterceptor() };
}
else
{
return Interceptors;
}
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Vincent-Philippe is a Senior Solution Architect working in Montreal (Quebec, Canada).
His main interests are Windows Azure, .NET Enterprise suite (e.g. SharePoint 2013, Biztalk Server 2010) & the new .NET 4.5 platforms.