RSS

Category Archives: C# tips

Using log4net with Ninject

I recently had to use log4net with ninject’s dependency injection framework and it’s logging extension. It took me a while to work it out and there didn’t seem to be a step by step guide to implementing it, so I decided to post one here.

This guide is in the context of implementing a Logger property from within a single class, in this case it was a RoleProvider to be used on a website. For the sake of the tutorial we’ll just create a simple class called SimpleRoleProvider, with a single method – GetRoles(string username):

namespace coalvilledave.tutorials.ninject
{
    using System;
    using Ninject;
    using Ninject.Extensions.Logging;
    using Ninject.Extensions.Logging.Log4net;
    using Ninject.Modules;

    public class SimpleRoleProvider
    {
        private ILogger _logger;

        public SimpleRoleProvider()
        {
        }

        public string[] GetRoles(string username)
        {
            string[] results = null;
            if (username == "coalvilledave")
            {
                results = new string[] { "Devs", "Admins", "Bloggers" };
            }
            else
            {
                _logger.Error("User {0} not found", username);
                results = new string[] { };
            }
            return results;
        }
    }
}

As you can see, pretty straightforward. All we need to do now is populate the _logger field. Our implementation of ILogger is provided by the Ninject.Extensions.Logging.Log4net.Infrastructure.Log4netLogger class, which wraps around the log4net logger class that we all know and love. The Ninject.Extensions.Logging.Log4net.Log4netModule binds an ILoggerFactory with a Log4netLoggerFactory class, which we then use to get our logger. We’ll be using an IKernel implementation to instantiate the ILoggerFactory, so let’s create a little method to return an IKernel (put it just below the parameterless constructor):

protected virtual IKernel CreateKernel()
{
    var settings = new NinjectSettings { LoadExtensions = false };

    //*** PLEASE NOTE, IN LATER VERSIONS OF THE NINJECT LOGGING EXTENSIONS, THE LOG4NET MODULE TYPE NAME IS Log4NetModule (capital 'N') ***
    return new StandardKernel(settings, new INinjectModule[] { new Log4netModule() });
}

Now all we need to do is plumb it all in. We’ll do this from the constructor so our class will initialise as soon as it is instantiated – add the following inside SimpleRoleProvider’s parameterless constructor:

var kernel = this.CreateKernel();
var loggerFactory = kernel.Get<ILoggerFactory>();
_logger = loggerFactory.GetCurrentClassLogger();

Ok, so now we just need to create a test harness of some sort, add the log4net specific stuff to the .config file and fire it up. I’ll just use a console app for this:

namespace coalvilledave.tutorials.ninject
{
    using System;

    public class SimpleRoleProviderTester
    {
        public static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure();
            var roleProvider = new SimpleRoleProvider();
            Console.WriteLine(roleProvider.GetRoles("coalvilledave"));
            Console.WriteLine(roleProvider.GetRoles("johnsmith")); // Will log an error
        }
    }
}

The first line is VERY important, if you don’t call

log4net.Config.XmlConfigurator.Configure()

You WON’T be able to find any of the loggers specified in your configuration file.

Finally, lets configure a Logger in the App.config or Web.config file:

<?xml version='1.0'?>
<configuration>

  <configSections>
    <section name='log4net' type='log4net.Config.Log4NetConfigurationSectionHandler, log4net'/>
  </configSections>

  <log4net>

    <appender name='TestLog' type='log4net.Appender.RollingFileAppender'>
      <file value='C:/ninjecttestlog.log'/>
      <appendToFile value='true'/>
      <rollingStyle value='Date'/>
      <datePattern value='ddMMyyyy'/>
      <layout type='log4net.Layout.PatternLayout'>
        <conversionPattern value='%date [%thread] %-5level %logger [%property{NDC}] - %message%newline'/>
      </layout>
    </appender>

    <root>
      <level value='INFO'/>
      <appender-ref ref='TestLog'/>
    </root>

    <logger name='coalvilledave.tutorials.ninject.SimpleRoleProvider' additivity='false'>
      <level value='INFO'/>
      <appender-ref ref='TestLog'/>
    </logger>

  </log4net>
</configuration>

Job done! – when you run the console app, the log should appear in C:\ninjecttestlog.log

 
15 Comments

Posted by on July 22, 2011 in C# tips, dotnet, logging, ninject