AOP is a buzzword or acronym from a couple of years back, that never really took wind in the world of .NET or statically typed languages. It is a programming model where you try to move out all infrastructure logic from the main flow of the program into aspects that should be deployed solution wide. This is very hard to accomplish in a statically typed language and that is the main reason for its failure, but the theory of AOP has lived on through academics and professional technologists. When Microsoft released version 1.2 of its dependency injection framework Unity, they also supplied support for AOP and they called it Policy Injection, in Enterprise Library 4, or plainly "interception" as a standalone Unity extension.
Building dependency chains
Unity is great at building dependency chains, because it was designed to do just that. By registering the dependency chain into a container you can simply ask that container to build you a CustomerRepository without the fuzz of creating a CustomerDataAccess and knowing where to find your instance of IDataFactory. This is also a great base to build our AOP model on.
var repository = Container.Instance.Resolve<CustomerRepository>(); var customer = repository.GetCustomerById(1);
The problem
A lot of our code may get repetitive where we use extensive logging that we would like to extract away from our code, since it is only noise. Please reflect over this example.
public Customer GetById(int id)
{
System.Diagnostics.Debug.WriteLine("CustomerDataAccess.GetById(" + id + ")"); // Noise
Customer result = null;
using (var connection = dataFactory.OpenConnection())
{
var command = connection.CreateCommand();
command.CommandText = "SELECT * FROM Customer WHERE id=" + id; // Beware of SQL injection
var reader = command.ExecuteReader();
result = reader.GetCustomer();
}
System.Diagnostics.Debug.WriteLine("CustomerDataAccess.GetById(" + id + ") -> " + result);
return result;
}
Wouldn't it be great if we could extract these log messages and place them outside the method?
Unity interception
With interception we can define what we would like to do before the call of a method, and after the call of a method. This way we can put the noise that is not business logic outside the method which will make the code much easier to read. We start by creating a call handler that will handle the call to the method we would like to intercept.
public class LogCallHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
string className = input.MethodBase.DeclaringType.Name;
string methodName = input.MethodBase.Name;
string arguments = GetArgumentList(input.Arguments);
/* CustomerDataAccess.GetById(123) */
string preMethodMessage = string.Format("{0}.{1}({2})", className, methodName, arguments);
System.Diagnostics.Debug.WriteLine(preMethodMessage);
/* Call the method that was intercepted */
IMethodReturn msg = getNext()(input, getNext);
string postMethodMessage = string.Format("{0}.{1}() -> {2}", className, methodName, msg.ReturnValue);
System.Diagnostics.Debug.WriteLine(postMethodMessage);
return msg;
}
public int Order { get; set; }
}
The call handler is a class that implements the ICallHandler from the Microsoft.Practices.Unity.InterceptionExtension assembly, where the Invoke method will be the method interrupting the call to our method. The method will not be run until we execute the following statement.
- getNext()(input, getNext);
The next thing you need is logic that will decide when a method should be interrupted. You can see this as a filter as every method that can be resolved through unity will be target for interception unless you filter it away. The implementation looks like this.
public class AnyMatchingRule : IMatchingRule
{
public bool Matches(MethodBase member)
{
return true;
}
}
I've written the easiest and dumbest matching rule ever. It will just match anything that comes in its way, and that will be enough for this simple example. If you need total control you might want a register of what method you should interrupt and match the MethodBase to that register. Just a thought. Now we only have to connect the dots. It looks like this.
public class Container : UnityContainer
{
public void Configure()
{
/* Register types into the container */
RegisterType<IDataFactory, StubDataFactory>();
RegisterType<IDataAccess<Customer>, CustomerDataAccess>();
/* Register our matching rule and call handler */
RegisterType<IMatchingRule, AnyMatchingRule>("AnyMatchingRule");
RegisterType<ICallHandler, LogCallHandler>("LogCallHandler");
/* Create a new policy and reference the matching rule and call handler by name */
AddNewExtension<Interception>();
Configure<Interception>().AddPolicy("LogPolicy")
.AddMatchingRule("AnyMatchingRule")
.AddCallHandler("LogCallHandler");
/* Make IDataAccess interface elegible for interception */
Configure<Interception>().SetInterceptorFor(typeof(IDataAccess<>), new TransparentProxyInterceptor());
}
}
In the first two lines we register our dependencies as usual. Then we also register the matching rule and the call handier that we've just created. You could create your own instances of these, but why when you have a container that can handle them. After that the interception configuration comes. It starts with adding the extension to the container. Then we register a new policy and add our matching rule and call handler to that policy. Last, we tell the container what type to intercept, and here we choose to intercept an open generic of the IDataAccess interface. That means that we will intercept any implementation of the IDataAccess, no matter if its generic class of Customer or something else. When we run the following code
var container = new Container(); container.Configure(); var dataAccess = container.Resolve<IDataAccess<Customer>>(); dataAccess.GetById(1);
We get this output
IDataAccess`1<AopExample.Customer>.GetById(1)
IDataAccess`1<AopExample.Customer>.GetById() -> Customer { Id = 1, Name = John Doe }
Where the logging actually comes from the LogCallHandler and not from the data access code. Neat huh? You can download the full example from here.

5 Comments
Mikael Lundin said
If you mean to intercept a static method and place behavior before and after it, I have to say no. This technique is all about Unity making it possible through resolving the class instance for you, and wrapping methods with functionality making AOP possible. Since static method aren't instance methods you can't intercept them.
:)
Interception with Unity « Mint said
[...] already written about this here but this is such a obscure topic that it really doesn’t hurt with some more [...]
Mikael Lundin said
Thank you Francillo for your comment.
First, the instance of IService that you want to intercept has to be resolved from the UnityContainer.
Second, if you're intercepting on an interface or abstract, the concrete class does not have to derive from MarshalByRefObject. This is only needed if you want to intercept directly on a concrete class.
Unity is one way in .NET to do AOP, but not the only way. I've also worked with two much easier frameworks
<ul>
<li><a href="http://www.castleproject.org/dynamicproxy/index.html" rel="nofollow">Castle.DynamicProxy</a></li>
<li><a href="http://code.google.com/p/linfu/" rel="nofollow">LinFu</a></li>
</ul>
Both are smaller frameworks and much easier to work with. Unity is larger and bulkier, but useful when you're in need of both IoC-container and Interception that are tightly integrated. What I don't like about Unity is its configuration that can get quite messy.
Then you have <a href="http://www.sharpcrafters.com/" rel="nofollow">PostSharp</a> that will modify the IL-code in compile time. I've never used it myself but heard good things about it.
francillo said
Hi,
Thx for this clear article.
But (always a but ;-) ), I adapt your example in my case. Same approach (in fact same pattern).
Unfortuantly, my "IService" is never intercepted (and matching rules always return true).
So I decided to intercept a basic implementation of my IService.
And I get: "The type MyServiceImplementation is not interceptable" (o_O).
I was told by microsoft that I must derive my service from "MarshalByRefObject", which is intrusive, and which ... do not work at all!!!
In fact, I come from the Java World where AOP is something "widly" used very easy to make it work ... (no troll or debate here, just a different approach).
Francillo.
itgoran said
Is there a way to do it with static method (without using PostSharp) ?