Posts Automatically inject log4net named logger using Ninject
Post
Cancel

Automatically inject log4net named logger using Ninject

When working with log4net you usually want that each class will have a named logger with the class full name (Namespace+Name).

the Log4Net examples shows this pattern:

1
2
3
4
5
6
7
8
public class MyClass
{
    // Define a static logger variable so that it references the
    // Logger instance named "MyClass".
    private static readonly ILog log = LogManager.GetLogger(typeof(MyClass));
 
   //Rest of the Class
}

 

this will create a logger instance with the class name and now in my log4net configuration I can write something like this:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<log4net>
    <!-- A1 is set to be a ConsoleAppender -->
    <appender name="A1" type="log4net.Appender.ConsoleAppender">
 
        <!-- A1 uses PatternLayout -->
        <layout type="log4net.Layout.PatternLayout">
            <!-- Print the date in ISO 8601 format -->
            <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
        </layout>
    </appender>
     
    <!-- Set root logger level to DEBUG and its only appender to A1 -->
    <root>
        <level value="DEBUG" />
        <appender-ref ref="A1" />
    </root>
     
    <!-- Print only messages of level WARN or above in the Namespace.SubNamespace.MyClass -->
    <logger name="Namespace.SubNamespace.MyClass">
        <level value="WARN" />
    </logger>
</log4net>

this configuration says that log messages for MyClass will only be written if they are in level WARN or up, all other loggers will be configured to DEBUG and up. the nice thing here is that I can now change logger name to “Namespace.SubNamespace” and this will affect all the loggers that their name is under “Namespace.SubNamespace”.

in my system I would like to loosen the coupling between MyClass and the Log4Net classes and take the creation process outside. the best way to achieve that is using Dependency Injection (DI).

but I still want each class to receive its own log (with logger name as class name). this is how It can be achieved using Ninject

1
2
3
4
5
6
7
8
var kernel = new StandardKernel();
kernel.Bind<IMyLogger>().ToMethod(ctx =>
{             
    var name = ctx.Request.Target.Member.DeclaringType.FullName;
    var loggerFactory = ctx.Kernel.Get<ILoggerFactory>();
    var log4Netlogger = loggerFactory.GetLogger(name);
    return new MyLogger(log4Netlogger);
});

IMyLogger is for the case you don’t want to your classes to know about log4net and prefer to stay with your own abstractions

This post is licensed under CC BY 4.0 by Tamir Dresher.

Catching exceptions from Caliburn.Micro ActionMessage invocation

Dealing with page resize in Windows Store Applications using Caliburn.Micro

Comments powered by Disqus.

Trending Tags