Search code examples
c#.netninjectlog4netnancy

Injecting ILogger using Ninject, Log4Net, and Nancy


I am currently working with an application that uses Ninject, Log4Net, and Nancy.

The issue I am having is determining the best way to persist the Log4Net configuration provided by the Web.config to all injected instances of ILogger.

Some context:

Within this application, we construct a single ninject StandardKernel, which automatically loads the Log4NetModule provided by Ninject.Extensions.Logging

Our Nancy Bootstrapper class inherits from NinjectNancyBootstrapper using this project

Using the above approach, we are able to successfully resolve the following property:

/// <summary>
/// Injected Logger
/// </summary>
[Inject]
public ILogger Logger { get; set; }

That relies on a Log4Net config provided within our Web.config.

Just prior to the creation of the static StandardKernel, we are executing the XmlConfigurator:

log4net.Config.XmlConfigurator.Configure();
_kernel = new StandardKernel();

From my understanding, this configurator should only need to be called one time in the application (which admittedly may be incorrect), prior to the creation of any ILogger instances. Upon starting my application, the first instance of the ILogger that is injected has the contained appenders that I would expect. Every subsequent call still successfully resolves the dependency, but is missing appenders present for the first configuration. Is there an intended behavior here that the XmlConfigurator will only apply to the first ILogger created? While this would definitely work in the case of using a single ILogger for the entire application, I would like at least one per type.

One of my initial attempts at solving this issue was attaching the XMLConfigurator into the RequestStartup method, but adds quite a lot of overhead to our API calls (nearly doubling the response time).

Maybe I'm approaching this problem entirely wrong, but I would like to know if anyone has suggestions and/or a solution to this problem.

Thanks.


Solution

  • You just need to register ILogger as a singleton service in Ninject Something like this:

    kernel.Bind<ILogger>.To<LoggerConstructor>().InSingletonScope();