Simple Example – AOP – Policy Injection with Unity

This is just a simple example explaining the processes/patterns to implement them using Unity 2.0, Dependency Inject, Inversion of Control (Ioc), and Aspect Oriented Programming (AoP). One of my primary goals is to not over complicate these examples. The examples should show how to do one thing and one thing only, but could possibly show how to implement these process/patterns in multiple way.

In this entry I will create a very simple application that shows how to do dependency injection, Interception and Policy Injection using Unity 2.0.

I’m using Unity 2.0 which is part of Enterprise Framework 5.0, and have created a very simple example application to test implementing AOP through Unity Interception. I’ve read a few articles on the web of how to use Unity with Interception and Policy Injection, and believe the articles from Dino Espisto were very benefical in help me figure this stuff out.
MSDN – Aspect-Oriented Programming, Interception and Unity 2.0
MSDN – Interceptors in Unity
MSDN – Policy Injection in Unity

If you are not aware of AOP, one of the primis is that Cross Cutting functionality, such as Loggin, should not be included in your domain classes.  My example contains a very simple console application that inlcudes using Interception that is configured through the Fluent API and a Configuration file.  The example also shows how to do Policy Injection and also configured using Fluent API and Configuration file.

For a contrived rule, emails should not be sent where the email address ends with “@Test.com”.  I have a class called EmailSerivce.  The EmailService is a fake, it doesn’t do anything other then sleep and print a message to the console.   I do not want to add any code to the EmailSerivce class that validates email; this should be handel by Unity Policy Injection.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AOP_Simple_Example
{
    interface IEmailService
    {
        bool SendEmail(string emailAddress);
    }

    public class EmailService : IEmailService
    {
        int _timeout;
        public EmailService(int timeout)
        {
            _timeout = timeout;
        }

        public virtual bool SendEmail(string emailAddress)
        {
            Console.WriteLine("Sending Email to {0}", emailAddress);
            System.Threading.Thread.Sleep(_timeout);
            return true;
        }
    }
}

Here’s the code that gets call using Unity Policy Injection. As you can see if the email address ends with “test.com”, then create a MethodReturn that includes true; otherwise go to the next step

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace AOP_Simple_Example
{
    public class IgnoreEmailCallHandler: ICallHandler
    {
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            IMethodReturn methodReturn;

            for (int i = 0; i < input.Arguments.Count; i++)
            {
                string paramName = input.Arguments.ParameterName(i);
                if (paramName == "emailAddress")
                {
                    string value = input.Arguments[i] as string;
                    if (value != null && value.ToLower().EndsWith("test.com"))
                    {
                        Console.WriteLine("!!! Test Email address {0}", value);
                        methodReturn = input.CreateMethodReturn(true);
                        return methodReturn;
                    }
                }
            }

            methodReturn = getNext().Invoke(input, getNext);
            return methodReturn;
        }

        public int Order{get;set;}
    }
}

Here the console application that actually load and configures the Unity Container.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace AOP_Simple_Example
{
    class Program
    {
        static void Main(string[] args)
        {
            bool isSuccessful;

            //Unity Policy Injection configured by Fluent API
            Console.WriteLine("***** Policty Injection configured by Fluent API");

            IUnityContainer containerPolicyFluenApi = GetPolicyInjectionContainerFromFluenApi();
            IEmailService emailServicePolicyFluentApi = containerPolicyFluenApi.Resolve(new ParameterOverride("timeout", 60));//Works
            isSuccessful = emailServicePolicyFluentApi.SendEmail("Policy@Test.com");
            isSuccessful = emailServicePolicyFluentApi.SendEmail("Policy@SomeDomain.com");
            Console.WriteLine("Is Successful {0}", isSuccessful);

            //Unity Policy Injection configured by Config File
            IUnityContainer containerPolicyConfig = GetPolicyInjectionContainerFromFluenApi();
            Console.WriteLine("***** Policty Injection configured by Configuration File");

            IEmailService emailServicePolicyConfig = containerPolicyConfig.Resolve(new ParameterOverride("timeout", 60));//Works
            isSuccessful = emailServicePolicyConfig.SendEmail("Policy@Test.com");
            isSuccessful = emailServicePolicyConfig.SendEmail("Policy@SomeDomain.com");
            Console.WriteLine("Is Successful {0}", isSuccessful);

            Console.ReadLine();
        }

        private static IUnityContainer GetPolicyInjectionContainerFromFluenApi()
        {
            IUnityContainer container = new UnityContainer();
            container.AddNewExtension();

            container.RegisterType(
                new InterceptionBehavior(),
                new Interceptor());

            container.Configure()
                .AddPolicy("IgnoreEmail")
                .AddMatchingRule(
                    new InjectionConstructor(
                        new InjectionParameter(typeof(IEmailService))))
                .AddMatchingRule(
                    new InjectionConstructor(
                        new InjectionParameter(new[] { "SendEmail", "Test" })))
                .AddCallHandler(
                    new ContainerControlledLifetimeManager(),
                        new InjectionConstructor());
            return container;
        }

        private static IUnityContainer GetPolicyInjectionContainerFromConfig()
        {
            var container = new UnityContainer();
            container.LoadConfiguration("PolicyInjection");

            return container;
        }
    }
}

Here's the configuration file that does the exact same thing as the Fluent API


  
  
    

4 thoughts on “Simple Example – AOP – Policy Injection with Unity”

  1. Just as you said, SIMPLE and EASY to understand. Thank you very much for sharing. Now I can start doing some AOP with unity i previously used PostSharp but it is not free anymore so I am switching to Unity.

    Thanks again! great post!

  2. There are a number of issues with this example.
    First of, the main() method calls GetPolicyInjectionContainerFromFluenApi() in both cases, when it’s supposed to call GetPolicyInjectionContainerFromConfig() to load configuration from the config file.
    Simple substitution does not work because of the following issues with the config:
    1. Assembly name in my case was “AOP_Simple_Example”, not “AOP Simple Example”.
    2. There is no param name “MembersToMatch” – it works with the param name “nameToMatch”.
    Otherwise, it’s a good example and it helps!

  3. One more imporatant change that I missed:
    3. In the config file, in the section the value for the injection parameter should be “IEmailService” (there is a typo in the example).
    Then it works.

Leave a Reply

Your email address will not be published. Required fields are marked *