Ninject to inject ILog dependency

2019-08-15 06:04发布

I have gone through some other posts in this forum that are related to Ninject and Log4net, but none seemed to address the issue (or resolve it).

Code looks like

IKernel kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = true }); 
kernel.Load(Assembly.GetExecutingAssembly());
Program pgm = new Program(kernel.Get<IFSLog>());

Exception is thrown in the last line above with message "Error activating ILog. No matching bindings are available... "

IFSLog is an interface defined in my assembly and its implementation has a dependency on the log4Net Ilog object as below

public class Log4NetLog : IFSLog {
  private ILog logger;
  public Log4NetLog(ILog log) {
    this.logger = log;
  }
  ...
}

The project references the Ninject.extensions.logging.log4net assembly, so my understanding is that the ILog binding should be identified from there.

Also tried the alternate way of specifying bindings manually

public class Bindings : NinjectModule {
    public override void Load() {
        Bind<IFSLog>().To<Log4NetLog>();
    }
}

and initializing kernel as

IKernel kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = false }, 
  new INinjectModule[] {new Bindings(), new Log4NetModule()});

Still same result. Any help much appreciated, thanks in advance...

1条回答
我命由我不由天
2楼-- · 2019-08-15 06:31

As it turns out, what Ninject.Extensions.Logging.Log4Net and Ninject.Extensions.Logging.NLog offer is an abstraction of the Log4net and Nlog interfaces, so you can easily swap NLog with Log4Net.

Both extensions only create a binding for Ninject.Extensions.Logging.ILoggerFactory and Ninject.Extensions.Logging.ILogger. So that's why there is no binding for ILog.

If you inject ILogger instead of ILog into your Log4NetLog : IFSLog it will work.

Or you can skip using the ninject extensions and wire it up yourself and use the log4net ILog interface directly (what are you using the IFSLog for?).

We used to use log4net ILog directly and simplified things like this:

internal class LogProvider : Provider<ILog>
{
    protected override ILog CreateInstance(IContext context)
    {
        Type typeLoggerIsInjectedInto = context.Request.ParentContext.Plan.Type;
        return LogManager.GetLogger(typeLoggerIsInjectedInto);
    }
}

IKernel.Bind<ILog>().ToProvider<LogProvider>();
查看更多
登录 后发表回答