One of the really cool aspects of Depency Injection is the ability to add functionality without changing existing code. A typical example of this might be implementing INotifyPropertyChanged or logging method calls. Using NInject 3.0 Interceptors it is very easy to do this. The interceptor intercepts all calls to the resolved object and allows you to add logging or whatever code you want to run. In NInject 3.0 the methods you intercept do NOT have to be virtual as well :) So how to set it up...
Getting the right assemblies.
Using Nuget just get NInject.Extensions.Interception.Linfu. This will also setup NInject 3.0 and NInject.Extensions.Interception.
Creating the logging Interceptor
This is just a sample interceptor that logs using Console.Writeline. Normally you would call something like Log4Net or your preferred logging framework. Implementing IInterceptor means you have to implement a Intercept method. The Intercept method gets a invocation as a parameter. By invocation.Proceed() the original method gets called. The logger first logs the method being called and the arguments it is called with. After the invocation.Proceed() it logs the result of the method call. The interceptor is pretty simple and can certainly be improved by creating nicer more custom messages.
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var methodName = invocation.Request.Method.Name;
try
{
var parameterNames = invocation.Request.Method.GetParameters().Select(p => p.Name).ToList();
var parameterValues = invocation.Request.Arguments;
var message = string.Format("Method {0} called with parameters ", methodName);
for (int index = 0; index < parameterNames.Count; index++)
{
var name = parameterNames[index];
var value = parameterValues[index];
message += string.Format("<{0}>:<{1}>,", name, value);
}
//log method called
LogMessage(message);
//run the intercepted method
invocation.Proceed();
//log method return value
if (invocation.Request.Method.ReturnType != typeof(void))
{
LogMessage(string.Format("Method {0} returned <{1}>", methodName, invocation.ReturnValue));
}
}
catch (Exception ex)
{
var message = string.Format("Method {0} EXCEPTION occured: {1} ", methodName, ex);
LogMessage(message);
throw;
}
}
private static void LogMessage(string message)
{
Console.WriteLine(string.Format("{0:HH:mm} {1}", DateTime.Now, message));
}
}
Adding the logging interceptor to your NInject Configuration
In your kernel configuration you can add interceptors to your bindings like this :
kernel.Bind<IService>().To<Service>().Intercept().With<LoggingInterceptor>();
Now when getting a IService using Kernel.Get<IService> the logginginterceptor will be interception all method calls :) A working sample console application can be found here:
SampleLogging.rar (2.86 mb)
SampleLogging.rar (2.86 mb)