Unity Interception Extension

maintain. Dependency injection also makes the applications easier to test and you can mock dependency to other systems.

Interception is a design pattern used to separate cross cutting concerns from the business logic and make it possible to apply it on different parts of the system when needed. For example to temporary monitor the load of a component or to apply extra trace message on a method.

An object must be interceptable before it is possible to apply different policies to it during runtime. A policy defines which handlers should execute for which method or object. For example to log a message before and after the execution of a method.

Unity has an interception extension and can resolve objects that are interceptable. It is possible to use the extension in combination with the configuration made in the Policy Application Block. That is, we can define which objects that shall be resolved as interceptable in the configuration file for Unity and use the policies entered in the configuration file for PIAB. I have worked with this and made a sample application that can be downloaded from here. Here follows a walkthrough of the solution.

I started with just creating a simple interface (IPerson) that is implemented by a class (Person). See code example below.

public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
string GetFullName();
}

public class Person: IPerson
{
public string FirstName { get; set; }
public string LastName {get; set;}

public string GetFullName()
{
return FirstName + ” ” + LastName;
}
}

I wanted to load the setup of unity from a configuration file. I added a container that loads the type mapping from the applications config file during the construction of the object.

public sealed class Container
{
private static readonly IUnityContainer container = new UnityContainer();
private static readonly Container instance = new Container();

private Container()
{
//Configure Unity
UnityConfigurationSection config = (UnityConfigurationSection
ConfigurationManager.GetSection(“unity”);

config.Containers.Default.Configure(container);
}

public static T Resolve<T>()
{
return container.Resolve<T>();
}
}

It’s common to keep Unity’s configuration in a separate file, since it tends to include a lot of information. I added a new configuration file called Unity.config to my project. I added the type aliases for my interface and my class. I also added the type mapping between them.

<unity>
<typeAliases>
<typeAlias alias=”IPerson” type=”UnityInterceptionLab.IPerson, UnityInterceptionLab” />
<typeAlias alias=”Person” type=”UnityInterceptionLab.Person, UnityInterceptionLab” />
</typeAliases>
<containers>
<container>
<types>
<type type=”IPerson” mapTo=”Person” />
</types>
</container>
</containers>
</unity>

In the app.config I can link to this file with the configSource attribute. First I have to register the unity section in the config file.

<configSections>
<section name=”loggingConfiguration” type=”Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />
<section name=”dataConfiguration” type=”Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />
<section name=“unity” type=”Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ requirePermission=”false”/>
</configSections>

Then I can link to the external file with the configSource attribute:

<unity configSource=”Unity.config”/>

I need this file during runtime and must make sure that it is copied to the output directory. This can be configured in the property sheet of the file by setting the option Copy to Output Directory to Copy Always.

The file is also needed during the unit tests and must be deployed when the tests run. This can be configured from the menu choice Test->Edit Test Run Configuration. Select Deployment and add the file.

I then created a unit test to make sure that the container worked.

[TestMethod]
public void UnityTest()
{
IPerson person = Container.Resolve<IPerson>();
person.FirstName = “John”;
person.LastName = “Doe”;
Assert.AreEqual(“John Doe”, person.GetFullName());
}

To integrate unity with interception, I must add an extension in the container. I added this to the constructor of the container. I also want to use the configuration of policies made in PIAB and have to register them as well. The updated container constructor becomes:

private Container()
{
//Configure Unity
UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(“unity”);
config.Containers.Default.Configure(container);

//Add interception extension
container.AddNewExtension<Interception>();

//Register the policy injection configuration
PolicyInjectionSettings policyInjectionSection = (PolicyInjectionSettings)GetSectionInConfigFile(assemblyConfigPath, PolicyInjectionSettings.SectionName);

if (policyInjectionSection != null)
{
policyInjectionSection.ConfigureContainer(container, new SystemConfigurationSource());
}
}

All code is now written and the rest is just about configuring the application. To configure that the resolved Person object shall be interceptable, I must add the extension to Interception in Unity.config file.

<container>
<extensions>
<add type=“Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception” />
</extensions>
<types>

An object can be interceptable by either implementing a known interface or by inheriting from the class MarshalByRefObject. I use a know interface and register a type alias for interface based interceptor in Unity.config.

<typeAlias alias=”InterfaceInterceptor” type=”Microsoft.Practices.Unity.InterceptionExtension.InterfaceInterceptor, Microsoft.Practices.Unity.Interception, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />

Then I can configure that the Person class shall be returned as interceptable in the extensionConfig section.

<extensionConfig>
<add name=”interception” type=”Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationElement, Microsoft.Practices.Unity.Interception.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″>
<interceptors>
<interceptor type=”InterfaceInterceptor”>
<key type=”IPerson” />
</interceptor>
</interceptors>
</add>
</extensionConfig>

To test this I set up a policy that logged a message before and after a method was called in the Person class. All configurations are included in the test project that you can download.

Peter

2 Comments

  1. Nice article. your link to the sample zip file is unable to extract. do you have this sample stored anywhere? thanks
    Bejoy

Leave a Reply

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