One fine day, my task was to refactor my classes so they did not have a dependency on log4net.
The first thing I did was to create an ILogger interface in my core library, and an Log4NetLogger class in my infrastructure library. Followed by adding a line to my IoC container bootstrapper class. Finally, I added an ILogger constructor argument to each of my classes that needed logging. Finished in no time, or so I thought.
I quickly realized that the contents of my log files had lost one important piece of information that nearly rendered them useless.
2009-04-07 07:10:15,810  DEBUG aspZone.LoggingExample.Log4NetLogger – Called Foo.DoSomething
2009-04-07 07:10:15,843  DEBUG aspZone.LoggingExample.Log4NetLogger – Called Bar.DoSomething
In my Log4NetLogger constructor, I had called LogManager.GetLogger as per common practice:
As a result, there was no way to filter my log entries by which logger they came from. Every single log entry looked like it came from Log4NetLogger. This had to change.
After a bunch of searching and a few tweets, I found what I think is a very neat solution.
I changed my ILogger interface to ILogger<T>:
And I modified my Log4NetLogger like this:
And using generic type inference, a syntax I was previously unaware of, to register the types in StructureMap:
The syntax for Ninject is very similar:
My log entries are filterable like they were before.
2009-04-07 07:10:15,810  DEBUG aspZone.LoggingExample.Foo – Called Foo.DoSomething
2009-04-07 07:10:15,843  DEBUG aspZone.LoggingExample.Bar – Called Bar.DoSomething
And now I have much better separation of concerns.