How to use InterfaceInterceptor of Unity with configuration file
After the long long days research of how to configure InterfaceInterceptor of Unity in the configuration file, posting the questions on the internet forums (e.g. codeplex and official MSDN forums), I got the help from codeplex forum, the problem was resolved at last. I searched almost whole internet with google, all AOP examples of Unity are using attribute based configurtion, these are not what I want. Here is my example of how to use InterfaceInterceptor of Unity with configuration file, but not attribute based.
C# Code
namespace AOPLearning
{
class Program
{
static void Main(string[] args)
{
try
{
IUnityContainer unityContainer = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(unityContainer);
IAccountContract service = unityContainer.Resolve<IAccountContract>();
service.Create();
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Type: {1}{0}{0}Message: {2}", Environment.NewLine, ex.GetType().Name, ex.Message));
}
Console.ReadKey(true);
}
}
public interface IAccountContract
{
void Create();
}
public class AccountService : IAccountContract
{
public void Create()
{
throw new InvalidOperationException("Withdraw error.");
}
}
[ConfigurationElementType(typeof(CustomHandlerData))]
public class NotificationHandler : IExceptionHandler
{
public NotificationHandler(NameValueCollection ignore)
{
}
public Exception HandleException(Exception exception, Guid handlingInstanceId)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(exception.Message);
return exception;
}
}
}
namespace AOPLearning
{
class Program
{
static void Main(string[] args)
{
try
{
IUnityContainer unityContainer = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(unityContainer);
IAccountContract service = unityContainer.Resolve<IAccountContract>();
service.Create();
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Type: {1}{0}{0}Message: {2}", Environment.NewLine, ex.GetType().Name, ex.Message));
}
Console.ReadKey(true);
}
}
public interface IAccountContract
{
void Create();
}
public class AccountService : IAccountContract
{
public void Create()
{
throw new InvalidOperationException("Withdraw error.");
}
}
[ConfigurationElementType(typeof(CustomHandlerData))]
public class NotificationHandler : IExceptionHandler
{
public NotificationHandler(NameValueCollection ignore)
{
}
public Exception HandleException(Exception exception, Guid handlingInstanceId)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(exception.Message);
return exception;
}
}
}
Configuraion Code
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, 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" />
</configSections>
<exceptionHandling>
<exceptionPolicies>
<add name="UIExceptionPolicy">
<exceptionTypes>
<add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="None" name="Exception">
<exceptionHandlers>
<add type="AOPLearning.NotificationHandler, AOPLearning, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Custom Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="boolean" type="System.Boolean, mscorlib" />
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
<typeAlias alias="interface" type="Microsoft.Practices.Unity.InterceptionExtension.InterfaceInterceptor, Microsoft.Practices.Unity.Interception" />
<typeAlias alias="TypeMatchingRule" type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule, Microsoft.Practices.Unity.Interception" />
<typeAlias alias="ExceptionCallHandler" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.ExceptionCallHandler, Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers" />
<typeAlias alias="IAccountContract" type="AOPLearning.IAccountContract, AOPLearning" />
<typeAlias alias="AccountService" type="AOPLearning.AccountService, AOPLearning" />
</typeAliases>
<containers>
<container>
<types>
<type type="IAccountContract" mapTo="AccountService">
<lifetime type="singleton" />
</type>
<type type="ExceptionCallHandler" name="ExceptionCallHandler">
<typeConfig>
<constructor>
<param name="exceptionPolicyName" parameterType="string">
<value value="UIExceptionPolicy" />
</param>
</constructor>
</typeConfig>
<lifetime type="singleton" />
</type>
</types>
<extensions>
<add type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception" />
</extensions>
<extensionConfig>
<add name="interception" type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationElement, Microsoft.Practices.Unity.Interception.Configuration">
<interceptors>
<interceptor type="interface">
<default type="IAccountContract" />
<key type="IAccountContract" />
</interceptor>
</interceptors>
<policies>
<policy name="IAccountContractPolicy">
<matchingRules>
<matchingRule name="TypeMatchingRule" type="TypeMatchingRule">
<injection>
<constructor>
<param name="typeName" parameterType="string">
<value value="AOPLearning.AccountService" type="string"/>
</param>
<param name="ignoreCase" parameterType="boolean">
<value value="true" type="boolean" />
</param>
</constructor>
</injection>
</matchingRule>
</matchingRules>
<callHandlers>
<callHandler type="ExceptionCallHandler" name="ExceptionCallHandler" />
</callHandlers>
</policy>
</policies>
</add>
</extensionConfig>
</container>
</containers>
</unity>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, 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" />
</configSections>
<exceptionHandling>
<exceptionPolicies>
<add name="UIExceptionPolicy">
<exceptionTypes>
<add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="None" name="Exception">
<exceptionHandlers>
<add type="AOPLearning.NotificationHandler, AOPLearning, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Custom Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="boolean" type="System.Boolean, mscorlib" />
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
<typeAlias alias="interface" type="Microsoft.Practices.Unity.InterceptionExtension.InterfaceInterceptor, Microsoft.Practices.Unity.Interception" />
<typeAlias alias="TypeMatchingRule" type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule, Microsoft.Practices.Unity.Interception" />
<typeAlias alias="ExceptionCallHandler" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.ExceptionCallHandler, Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers" />
<typeAlias alias="IAccountContract" type="AOPLearning.IAccountContract, AOPLearning" />
<typeAlias alias="AccountService" type="AOPLearning.AccountService, AOPLearning" />
</typeAliases>
<containers>
<container>
<types>
<type type="IAccountContract" mapTo="AccountService">
<lifetime type="singleton" />
</type>
<type type="ExceptionCallHandler" name="ExceptionCallHandler">
<typeConfig>
<constructor>
<param name="exceptionPolicyName" parameterType="string">
<value value="UIExceptionPolicy" />
</param>
</constructor>
</typeConfig>
<lifetime type="singleton" />
</type>
</types>
<extensions>
<add type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception" />
</extensions>
<extensionConfig>
<add name="interception" type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationElement, Microsoft.Practices.Unity.Interception.Configuration">
<interceptors>
<interceptor type="interface">
<default type="IAccountContract" />
<key type="IAccountContract" />
</interceptor>
</interceptors>
<policies>
<policy name="IAccountContractPolicy">
<matchingRules>
<matchingRule name="TypeMatchingRule" type="TypeMatchingRule">
<injection>
<constructor>
<param name="typeName" parameterType="string">
<value value="AOPLearning.AccountService" type="string"/>
</param>
<param name="ignoreCase" parameterType="boolean">
<value value="true" type="boolean" />
</param>
</constructor>
</injection>
</matchingRule>
</matchingRules>
<callHandlers>
<callHandler type="ExceptionCallHandler" name="ExceptionCallHandler" />
</callHandlers>
</policy>
</policies>
</add>
</extensionConfig>
</container>
</containers>
</unity>
</configuration>