AOP – Interception with Unity

Interception is a design pattern that is designed for cross-cutting concerns, issues that cut across the entire software. For example, you always wrap a function with Stopwatch to find out how long a function took to execute. Often you would like to check the cache before you will call a function to retrieve an object etc. Logging and exception handling can be other actions you would like to do, similar code you write again and again. Makes your code bloat and you suffer from ‘carpal tunnel syndrome’. Enter aspect-oriented programming (AOP), AOP is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. Aspect-oriented programming entails breaking down program logic into distinct parts (so-called concerns, cohesive areas of functionality), some concerns are called crosscutting concerns because they “cut across” multiple abstractions in a program.

Unity from enterprise library provides support for interception through the Interception container extension. When you look at many of these cross-cutting concerns, you can recognize a pattern. Many of them happen  at the start or the end of a method. Most of time you can put some special handling code before or after method calls to handle the cross-cutting concerns. Unity interception will help you  get the common code out of the methods and enhance its maintainability and readability.

Unity provides an excellent documentation and example here, but as it is a book, it is elaborate and has lot of details. I want to simplify and write a ‘hello world’ which can explain the concept in few lines. Once you are done with this sample and see how it is working, you need to go back to Unity book and understand it deeply.

Here is a code, we have an App object and we are calling a “Run” method on it. This method is going to log execution time. As you can see, there is nothing in this code which is doing the stopwatch business. Similarly, you can see the “Run” method has nothing but its business logic.  This is the simplicity of AOP, your code remain clean with out the clutter of repeated code.


using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;

namespace MEFUI
{
    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer _container = new UnityContainer();
            _container.AddNewExtension<Interception>();

            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Configure(_container, "containerOne");
            IApplication app = _container.Resolve<Application>();

            string s = app.Run();

            Console.WriteLine(s);

            Console.ReadLine();
        }
    }
    public interface IApplication
    {
        string Run();
    }

    public class Application : IApplication
    {
        public virtual string Run()
        {
            Console.WriteLine("Hello world");
            return "This is my return value";
        }
    }
}

In the above code, all the magic is done by five lines of Unity code, plus a config file. Config file tells the type which need to be intercepted and by whom.

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
             Microsoft.Practices.Unity.Configuration, Version=3.0.0.0,  Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>

  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension,     Microsoft.Practices.Unity.Interception.Configuration" />
    <namespace name="MEFUI.Program" />
    <assembly name="MEFUI" />
    <container name="containerOne">
      <register type="MEFUI.IApplication, MEFUI" mapTo="MEFUI.Application, MEFUI">
        <!--<interceptor type="InterfaceInterceptor" />-->
        <interceptor type="VirtualMethodInterceptor"  />
        <interceptionBehavior type="MEFUI.Interceptor, MEFUI"  />
      </register>
    </container>
  </unity>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
  </startup>

  <runtime>
       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
           <dependentAssembly>
               <assemblyIdentity name="Microsoft.Practices.Unity" publicKeyToken="31bf3856ad364e35" culture="neutral" />
               <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
           </dependentAssembly>
       </assemblyBinding>
   </runtime>
</configuration>

So where is the interception happening?  To create an interceptor, you need to define a interceptor object, which must impelement IInterceptionBehavior. You can read about IInterceptionBehavior in Unity Book. But in short, you have to worry about only Invoke method. Method is invoked by the following line.

msg = getNext() (input, getNext);

and you can wrap this line with other aspects. I wrapped here with stopwatch, you can wrap it with checking cache, logging, error handling or format a hard disk etc.

using System;
using System.Collections.Generic;
using Microsoft.Practices.Unity.InterceptionExtension;
using System.Diagnostics;

namespace MEFUI
{
    public class Interceptor : IInterceptionBehavior
    {
        public Interceptor()
        {
        }

        public IEnumerable GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            IMethodReturn msg = null;

            //Pre method calling
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

           // Method is invoked
            msg = getNext()(input, getNext);

            //Post method calling
            stopwatch.Stop();
            Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
            return msg;
        }

        public bool WillExecute
        {
            get
            {
                return true;
            }

        }
    }
}

This is it.  To implement Interception using Unity that’s all you need to know. However, to understand deeply, read more about Unity and interception here.  Start with decorator pattern, get the unity code from here.

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