How to Inject Log4Net ILog implementations using Unity 2.0

Viewed 30321

Ultimately this has to do with setting up log4Net but generically the problem is not logging specific.

Generically what I am trying to figure out is how to do, in Microsoft Unity 2.0, something equivalent to what one gets with the Castle.Facilities.Logging.LoggingFacility. Namely the ability to declare a dependency on a logger and have the logger initialized with the Type of the object into which it is being injected.

In the spirit of a test is worth a thousand words, here is what I need:

class Logger_IOC_Tests
{
    //[Test] 
    public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
    {
        var container = new UnityContainer();
        /* Configuration Magic probably involiving registering either 
            * a custom IDependencyResolverPolicy or BuilderStrategy
            * goes here...
            */
        container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());

        var user = container.Resolve<LoggerUser>();

        Assert.True(user.Logger.GetUserType() == user.GetType());
    }
}

interface ILogger
{
    Type GetUserType();
}

class Logger : ILogger
{
    private readonly Type _type;

    public Logger(Type type)
    {
        _type = type;
    }

    public Type GetUserType()
    {
        return _type;
    }
}

class LoggerUser
{
    public readonly ILogger Logger;

    public LoggerUser(ILogger logger)
    {
        Logger = logger;
    }
}
6 Answers

With Unity 5 and above, you can now use Unity's own Log4Net extension from https://github.com/unitycontainer/log4net.

All you have to do is install the Nuget and add the extension to your container:

container.AddNewExtension<Log4NetExtension>();

And it will work automatically with any classes that use ILog as a dependency.

You can use the following code to inject Log4Net

log4net.Config.BasicConfigurator.Configure();    

container.RegisterType<ILog>(new InjectionFactory(x => LogManager.GetLogger(typeof(Program))));

typeof(Program) is used since I'm registering in program class. Use can use the class name or this keyword

Then you can inject ILog into the class

 public class MyClass
 {
   private readonly ILog logger;

   public MyClass(ILog logger)
   {
     this.logger = logger;
   }
 }
Related