A technical post for a change! For a while I’ve been intrigued at the possibilities that things like DI and AOP provide. I finally managed to implement one of my nebulous ideas: that of automatic logging. I achieved this with a simple StructureMap interceptor, and a Castle.DynamixProxy Interceptor. My solution is cobbled together from various pieces, most notable Ayende’s post, and this StructureMap Google Group conversation.
Herewith the code:
public class LogTypeInterceptor : StructureMap.Interceptors.TypeInterceptor
{
private readonly ProxyGenerator proxyGenerator = new ProxyGenerator();
public bool MatchesType(Type type)
{
if (type.IsSealed)
return false;
if (!type.Namespace.Contains("<root-namespace>"))
return false;
if (type.Namespace.Contains("Infrastructure"))
return false;
return true;
}
public object Process(object target, IContext context)
{
return proxyGenerator.CreateInterfaceProxyWithTargetInterface(
target.GetType().GetInterfaces().First(),
target.GetType().GetInterfaces(),
target, new LogInterceptor());
}
}
The LogInterceptor class referenced above is lifted verbatim from Ayende’s post (his class is named LoggingInterceptor).
The last piece of the puzzle is to register the Interceptor with StructureMap:
RegisterInterceptor(new LogTypeInterceptor());
Now, all types registered with the container will be ‘wrapped’ with the LogInterceptor (by being proxied). A log statement will be emitted each time any interface or virtual method is called on any registered type.