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.