Intercept calls to objects in C#


The best types in object oriented systems are ones that have a single responsibility.
But as systems grow, other concerns tend to creep in. System monitoring, such as
logging, event counters, parameter validation, and exception handling are just some
examples of areas where this is common. If we implement these cross cutting concerns,
it will require large amounts of repetitive code in application. Intercepting calls
to object is not direct implementation in .Net as it doesn’t support full Aspect
Oriented programming concepts (like cross cutting, point cut etc ).There are many
library available which supports AOP concepts in .Net like AspectF, Unity,
PostSharp, Spring.Net etc..

I am taking example from Unity Framework to intercept calls to object.

For example if I want to log every method call in class then we will need to put
logging block in all methods, this is repetitive process.

Following code is syntax for interception call:

           IUnityContainer container = new UnityContainer();
        container.AddNewExtension<Interception>();
	    container.RegisterType<TypeToIntercept>(
		new Interceptor<VirtualMethodInterceptor>(),
		new InterceptionBehavior<ABehavior>(),
		new> AdditionalInterface<IOtherInterface>());

I start with concrete implementation of above code:

static void Main( string[] args)
{
    IUnityContainer container = new UnityContainer();
    container.AddNewExtension<Interception>();
    container.RegisterType<IDAL, DAL>(
    new Interceptor<VirtualMethodInterceptor>(), new InterceptionBehavior<Interceptor>()
    );
    IDAL dal = container.Resolve<IDAL>();
	dal.MethodForLoggingA();
	Console.Read();
}

Interceptor is class which encapsulate interceptor behavior and should implement
IInterceptionBehavior interface. Invoke method will be call before every method
that is intercepted.

	public class Interceptor : IInterceptionBehavior
	{
	public IEnumerable
 GetRequiredInterfaces()
       {
              return Type.EmptyTypes;
          }

          public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
          {
              /* Call the method that was intercepted */
              string className = input.MethodBase.DeclaringType.Name;
              string methodName = input.MethodBase.Name;

			string generic = input.MethodBase.DeclaringType.IsGenericType ? string.Format("", 
			input.MethodBase.DeclaringType.GetGenericArguments().ToStringList()) : string.Empty;

              string arguments = input.Arguments.ToStringList();
   
              string preMethodMessage = string.Format("{0}{1}.{2}({3})", className, generic, methodName, arguments);
              Console.WriteLine("PreMethodCalling: " + preMethodMessage);
              //Logging
              Logger.Instance.Log(preMethodMessage);
              //Invoke method
              IMethodReturn msg = getNext()(input, getNext);
              //Post method calling
              string postMethodMessage = string.Format("{0}{1}.{2}() -> {3}", className, generic, methodName, msg.ReturnValue);
              Console.WriteLine("PostMethodCalling: " + postMethodMessage);
              //Logging
              Logger.Instance.Log(postMethodMessage);
              return msg;
          }
   
          public bool WillExecute
          {
              get { return true; }
          }
      }

     public class DAL : AOPExample.IDAL
      {
          public virtual void MethodForLoggingA()
          {
              Console.WriteLine("Called MethodForLoggingA");
          }
          public void MethodForLoggingB()
          {
              Console.WriteLine("Called MethodForLoggingB");
          }
          public void MethodForLoggingC()
          {
              Console.WriteLine("Called MethodForLoggingC");
          }
  }

Above Invoke method will call before method, you can execute any code before and
after called method. getNext() delegate type is passed
to each interceptor’s Invoke method.  Call the  delegate to get the next
delegate to call to continue the chain.

Output

PreMethodCalling: DAL.MethodForLogingA()

Calling MethodForLogingA

PostMethodCalling: DAL.MethodForLoggingA() –>

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: