【问题标题】:Ninject to inject ILog dependencyNinject 注入 ILog 依赖
【发布时间】:2014-07-10 14:17:16
【问题描述】:

我在这个论坛上浏览了一些与 Ninject 和 Log4net 相关的其他帖子,但似乎没有一个解决问题(或解决问题)。

代码看起来像

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

在上面的最后一行抛出异常,消息“激活 ILog 时出错。没有匹配的绑定可用...”

IFSLog 是在我的程序集中定义的接口,它的实现依赖于 log4Net Ilog 对象,如下所示

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

该项目引用了 Ninject.extensions.logging.log4net 程序集,所以我的理解是应该从那里识别 ILog 绑定。

还尝试了手动指定绑定的替代方法

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

并将内核初始化为

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

还是一样的结果。非常感谢任何帮助,在此先感谢...

【问题讨论】:

  • 你的IFSLog引用的是哪个版本的log4net? 可能 ninject 扩展引用了不同的版本。
  • log4net 版本是 1.2.13.0,ninject.extensions.logging.log4net 是 3.2.0.0。作为一种解决方法,我添加了一个自定义 ILogFactory 接口,该接口具有一个 GetLogger 方法,该方法将在内部调用 LogManager.GetLogger,然后用这个新接口替换 IFSLog 运行时依赖项。在各种类中,我通过调用 ILogFactory.GetLogger 来初始化 ILog 成员......虽然它有效,但仍然不确定为什么早期的尝试没有......谢谢
  • 好吧,我只是想知道这是否是由 ninject.extensions.logging.log4net (3.2.0.0) 引用 log4net 1.2.11 引起的,而您引用的是不同的版本 (1.2.13.0)。也许你可以降级到 1.2.11 看看会发生什么?我们曾经在 log4net 上遇到过类似的问题。老实说,您使用 ninject log4net 日志记录扩展是为了什么?它只是一堆简单的类(日志接口的包装器..)+ 1 或 2 个绑定,我会自己动手。

标签: ninject log4net


【解决方案1】:

事实证明,Ninject.Extensions.Logging.Log4Net 和 Ninject.Extensions.Logging.NLog 提供的是对 Log4net 和 Nlog 接口的抽象,因此您可以轻松地将 NLog 与 Log4Net 交换。

这两个扩展只为Ninject.Extensions.Logging.ILoggerFactoryNinject.Extensions.Logging.ILogger 创建一个绑定。这就是ILog 没有绑定的原因。

如果您将ILogger 而不是ILog 注入您的Log4NetLog : IFSLog,它将起作用。

或者您可以跳过使用 ninject 扩展并自己连接它并直接使用 log4net ILog 接口(您使用 IFSLog 做什么?)。

我们以前直接使用 log4net ILog 并简化如下:

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>();

【讨论】: