I am struggling with a lifestyle issue when injecting my logger.
NLog expects instances to be created "Instance per Dependency", as described here - https://simpleinjector.readthedocs.io/en/latest/lifetimes.html#instance-per-dependency.
Logger creation is done using a factory method LogManager.GetCurrentClassLogger()
. Using this pattern allows the logger to obtain the name of the caller in order to include it in logged messages.
Simple Injector tells me that my Transient logger cannot be injected into a singleton. But I cannot change the lifestyle to Singleton because I would then lose the context information about which class is calling the logger.
My implementation is below:
I have written a factory that creates the NLog instance and returns it in a wrapper that implements my own ILogger abstraction:
internal class LoggerFactory : ILoggerFactory
{
public ILogger GetLogger()
{
return new NLogLogger(LogManager.GetCurrentClassLogger());
}
}
I registered this with Simple Injector thus:
container.RegisterSingleton<ILoggerFactory, LoggerFactoryInstance>();
container.Register<ILogger>(
() => container.GetInstance<ILoggerFactory>().GetLogger());
And I depend on the ILogger interface in my classes that need logging:
public class MyClass
{
private readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
}
Do I have to inject the factory? I would rather not have to resolve the logger everywhere I want to use it, but perhaps this is what Simple Injector would expect?
How are other people dealing with this? Is there a better way?