2

I have a LogManager class which has a type parameter to give to log4net like this:

public class LogManager<T> : ILogManager
{
    private ILog Logger { get; set; }

    public LogManager()
    {
        Logger = LogManager.GetLogger(typeof(T));
    }
}

And I register this logger as conditional:

container.RegisterConditional(typeof(ILogManager),
c => typeof(LogManager<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);

It works like it supposed to, I inject the log manager to my controllers' constuctors and use it. But there is a problem. I have a lot of singleton classes that should use the log manager too, but I can't inject it to them because log manager has a shorter life then others, so Simple Injector won't allow me to do it.

The proposed solution is to inject a log factory class to the other singletons and call the factory every time which sounds like a bad idea. I don't want to do _logFactory.GetLogger().Debug("log") every time I want to log something. Or I am missing something about this solution?

The other proposed solution is to make singleton classes transient which doesn't make any sense.

Any suggestions how should I proceed? Is there anything wrong with my design?

gmnnn
  • 339
  • 1
  • 3
  • 19

1 Answers1

3

You should make the registration singleton:

container.RegisterConditional(typeof(ILogManager),
    c => typeof(LogManager<>).MakeGenericType(c.Consumer.ImplementationType),
    Lifestyle.Singleton,
    c => true);

Since LogManager<> is a generic type, Simple Injector will create one instance per closed generic version. So LogManager<HomeController> is a different instance than LogManager<UsersController>. This is simply because there is no way to use the same instance (this is impossible in .NET). So each consumer will still have its own LogManager<T> and with that its own log4net ILog implementation. The loggers returned from log4net's LogManager.GetLogger are thread-safe, and that's why its no problem to make your own LogManager<T> singleton.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • You are rigth, I was a little confused about this. Wouldn't it be a problem to have more than 300 controllers which means more than 300 different logger instances? – gmnnn Apr 28 '16 at 06:41
  • @gmmm From a perspective of memory consumption, there will hardly be a problem, but you absolutely do have a maintainability problem when you inject your logger into so many classes. Please read [this answer](https://stackoverflow.com/a/9915056/264697) – Steven Apr 28 '16 at 06:49
  • that was the answer that got me thinking :) I will try to simplify the classes. – gmnnn Apr 28 '16 at 07:05