Creating a simple logging Interceptor using NInject 3.0

8. oktober 2013 20:52 by martijn in .net, DRY, ninject

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)