Software Architecture-Interception with Unity(Decorator pattern)

Previous Related posts:
Software Architecture- C# – Unity 2.0 – First lession
Software Architecture C-Sharp Unity-2.0 Second Lession
Software Architecture – C#- Unity-2.0-Creating Instance Registrations
Software Architecture-Dependency Injection with Unity for Constructor Injection

According to Unit Documentation:

Unity interception enables you to effectively capture calls to objects and add additional functionality to the target object. Interception is useful when you want to modify the behavior for individual objects but not the entire class, very much as you would do when using the Decorator pattern. It provides a flexible approach for adding new behaviors to an object at run time.

For definition of decorator pattern, please visit wiki link as below:
http://en.wikipedia.org/wiki/Decorator_pattern
Interception process is explained below as:

For exact details about Interception by Unity visit, MSDN at:
http://msdn.microsoft.com/en-us/library/ff660891(v=pandp.20).aspx
Lets create a Calculator which provide implementation for adding 2 numbers.
For that create a Calculator class which implements calculator interface as below:

public interface ICalculator
    {
        [InterceptorAttribute]
         int AddMe(int a, int b);
    }
class Calculator:ICalculator
    {
        public int AddMe(int a, int b)
        {
            if (a == 0 && b == 0)
                throw new Exception("Dummy input....");
            else
            return a + b;
        }
    }

Note that AddMe method in interface is decorated with a attribute named “InterceptorAttribute” which is explained below:
Let implement ICallHandler, as below:

// Summary:
    //    Handlers implement  ICallHandler interface and are called for each invocation of the
    //     pipelines that they're included in.
    class InterceptorCallHandler : ICallHandler
    {
        // Summary:
        //     Implement this method to execute your handler processing.
        //
        // Parameters:
        //   input:
        //     Inputs to the current call to the target.
        //
        //   getNext:
        //     Delegate to execute to get the next delegate in the handler chain.
        //
        // Returns:
        //     Return value from the target.
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {           
            Console.WriteLine("Entering "+ this.GetType().Name + "'s Method Invoke" );
            
            //Pre-Method call processing
            Console.WriteLine("Pre-Method call processing - Input Parameters:");
            foreach (var parameter in input.Arguments)
            {
                Console.WriteLine(parameter.ToString());
            }
            // Actual call to method
            IMethodReturn result = getNext()(input, getNext);

            //Post method call processing
            Console.WriteLine("Post method call processing - Output Parameters:" + ((result.ReturnValue!=null)? result.ReturnValue.ToString():""));

            // Exception passed by call
            if (result.Exception != null)
            {
                Console.WriteLine("Exception :" + result.Exception.Message);                                                
                Console.WriteLine("Stacktrace :");
                Console.WriteLine(Environment.StackTrace);
            }
            Console.WriteLine("Leaving " + this.GetType().Name + "'s Method Invoke");
            
            return result;
        }

        public int Order { get; set; }
    }

Let define an attribute as below:

// Summary:
    //    HandlerAttribute is Base class for handler attributes used in the attribute-driven interception
    //     policy.
    class InterceptorAttribute : HandlerAttribute
    {

        // Summary:
        //     Derived classes implement this method. When called, it creates a new call
        //     handler as specified in the attribute configuration.
        //
        // Parameters:
        //   container:
        //     The Microsoft.Practices.Unity.IUnityContainer to use when creating handlers,
        //     if necessary.
        //
        // Returns:
        //     A new call handler object.
        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
            {            
                 return new  InterceptorCallHandler();
                }
    }

Now every thing is wired up, so let do some testing with above implementation as below:

// define container
            IUnityContainer myContainer = new UnityContainer();
            // add extension for interception
            myContainer.AddNewExtension<Interception>();
            myContainer.RegisterType<ICalculator, Calculator>().Configure<Interception>()
                .SetInterceptorFor<ICalculator>(  new InterfaceInterceptor());
            // resolve
            ICalculator iCal = myContainer.Resolve<ICalculator>();
            //Test case  1
            Console.WriteLine("Going to call to AddMe method with input 3, 4:");
            Console.WriteLine("Call to AddMe method with input 3, 4 - Result is: " + iCal.AddMe(3, 4));
            //Test case  2
            try
            {
                Console.WriteLine("Going to call to AddMe method with input 0, 0:");
                Console.WriteLine("Call to AddMe method with input 0, 0 - Result is: " + iCal.AddMe(0, 0));
            }
            catch { }
            Console.ReadKey();  

The Output will be as below:

The above code create unity Container, then a extension for interception is added, then type is registered, resolved to get a instance of calculator.
Then in Test Case 1, AddMe method is called with input 3,4. This call is intercepted via InterceptorAttribute and Pre-processing before the call [Input parameters are printed to Console] and Post-processing after the call is done [Result parameters are printed to Console]. Anything can be done in these locations. This is decorator pattern.
Then in Test Case 2, AddMe method is called with input 0,0, this call is again intercepted via InterceptorAttribute and Preprocessing before the call [Input parameters are printed to Console]and Post-Processing after the call is done[Exception is handled and Call stack is printed on Console.] This is again decorator pattern implementation.

Download complete source code here.
[After downloading the file, rename “unity2interceptioncalculatorapp-zip.doc” to “Unity2InterceptionCalculatorApp.zip” and extract the files]

So that is how interception works in Unity Container.
Keep Enjoying Unity 2.0

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

%d bloggers like this: