RoBlog – Refactoring Reality

Discrete thought packets on .Net, software development and the universe; transmitted by Rob Levine

Using log4net with Unity

by Rob Levine on 28-Dec-2012

[EDIT: the Unity extension described here is now available as a NuGet package. See this post for more information]

When using log4net, it is quite common to create loggers for each class using something like:

1
2
3
4
public class MyClass
{
   private static readonly ILog logger = LogManager.GetLogger(typeof(MyClass));
}

I’ve been following this pattern for years, but more recently it has begun to bother me. I tend to use Unity and constructor injection for most dependency injection requirements I have, but the above logger pattern doesn’t fit nicely into this dependency injection approach. I would really like to be able to write the following code and receive a similarly configured logger:

1
2
3
4
5
6
7
8
9
public class MyClass
{
    private readonly ILog logger;
 
    public MyClass(ILog logger)
    {
        this.logger = logger;
    }
}

There has been some discussion online as to how best to acheive this:

http://stackoverflow.com/questions/6846342/how-to-inject-log4net-ilog-implementations-using-unity-2-0
http://davidkeaveny.blogspot.co.uk/2011/03/unity-and-log4net.html
http://blog.baltrinic.com/software-development/dotnet/log4net-integration-with-unity-ioc-container

In the last of these links, Kenneth Baltrinic describes a solution. However, although his solution works, it involves some stack walking to identify the Type of the logger to create. I felt that this should be available from within Unity itself without the need to resort to handling StackTrace/StackFrame classes, and so I set about writing a solution to the problem in a similar vein to Kenneth’s, but using the hooks within Unity to track the object creation stack and to be able to work out “for whom am I creating this ILog instance”?

I ended up writing three extensions, all of which can be found here:

https://github.com/roblevine/UnityLog4NetExtension

They are:

CreationStackTrackerExtension

This extension is responsible for maintaining a stack of the type creation heirarchy. At the creation of any given type via unity, the stack provided by this extension will show the parent class, grandparent, etc. This extension is used by both the extensions listed below.

Log4NetExtension

Relying on the extension above, this intercepts any request for an ILog instance and creates an ILog instance by calling LogManager.GetLogger(Type t) using the type of the parent class (ie the class the logger is being injected into)

CreationStackReporterExtension

Relying on the CreationStackTrackerExtension extension above, this extension will resolve any dependency of type UnityObjectCreationStack, and inject an instance that has a copy of the object creation stack, as maintained by CreationStackTrackerExtension.

So now, by simply registering the appropriate extension:

1
2
   var container = new UnityContainer();
   container.AddNewExtension();

I can have the correct ILog implementation injected into my class.

4 thoughts on “Using log4net with Unity

  1. Jdogg13 says:

    Thanks, this is just what I was looking for. Would be really cool if this were a nuget package.

  2. Rob Levine says:

    @Jdogg13 – thanks for the feedback. I’ll try and find time to clean up the code and package it up.

  3. Ali Reza Dehdar says:

    Great work! Now my code will look much cleaner. Thanks 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *