Ninject.Extensions.Logging.Log4net 意外行为
我通过 Ninject 的 (2.2.1.4) Extensions.Logging.Log4net (2.2.0.4) 使用 Log4Net (1.2.10) 时遇到问题,通过 NuGet 安装。
当我直接访问 Log4Net 时:
var logger = log4net.LogManager.GetLogger("Log4NetLoggerTest");
logger.Debug("foo { bar");
结果是:
2011-08-29 10:02:02,071 [9] DEBUG Log4NetLoggerTest foo { bar
但是,当通过 Ninject 访问记录器时:
using (IKernel kernel = new StandardKernel())
{
var ninjectLogger = kernel.Get<NinjectLoggerTest>();
ninjectLogger.Log.Debug("foo { bar");
}
其中 NinjectLoggerTest 只是这样:
using Ninject.Extensions.Logging;
namespace TestApp
{
public class NinjectLoggerTest
{
public NinjectLoggerTest(ILogger log)
{
Log = log;
}
public ILogger Log;
}
}
有点出乎意料的是,结果是:
2011-08-29 10:29:27,114 [10] DEBUG TestApp.NinjectLoggerTest <log4net.Error>Exception during StringFormat: Input string was not in a correct format. <format>foo { bar</format><args>{}</args></log4net.Error>
更糟糕的是,当使用 ILogger 的 Trace 方法时,存在 type 的第一次机会异常mscorlib.dll 中的“System.FormatException”
我做错了什么吗?我该如何解决这个问题?
TIA
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案是创建一个简单的记录器外观,将 Ninject 与应用程序的其余部分完全解耦。步骤是:
1) 将 Ninject 的 ILogger 接口复制/粘贴到应用程序的命名空间中(不要只是继承,否则您最终会依赖 Ninject 的程序集,因为通过 Ninject 的 ILogger 公开的类型)。
2) 创建自定义 Logger、LoggerFactory 和 LoggerModule 类。
3) 将 LoggerModule 传递给 Ninject 的 StandardKernel
为了完整起见,代码是:
Ninject 的 ILogger - 复制/粘贴 ILogger 接口,将其命名空间更改为 MyAppNamespace.Logger 并添加以下方法:
Logger.cs
LoggerFactory.cs
LoggerModule.cs
将整个混乱放入一个单独的类库中,使其成为唯一依赖于 Ninject 日志扩展和具体记录器的部分。现在,您可以在整个应用程序中使用 MyAppNamespace.ILogger,如下所示:
LoggerTest.cs
Main.cs Main 中某处的
最终取决于 Ninject,但不取决于日志扩展以及您使用的任何记录器(该代码适用于 Log4Net,您需要调整NLog 的一点)。应用程序的其他部分依赖于 MyAppNamespace.ILogger。就是这样。
The solution is to create a simple logger façade to completely decouple Ninject from the rest of the app. The steps are:
1) Copy/paste Ninject's ILogger interface into the app's namespace (do not just inherit or you end up depending on Ninject's assembly because of the types exposed through Ninject's ILogger).
2) Create custom Logger, LoggerFactory and LoggerModule classes.
3) Pass LoggerModule to Ninject's StandardKernel
For completeness the code is:
Ninject's ILogger - copy/paste the ILogger interface, change it's namespace to MyAppNamespace.Logger and add the following methods:
Logger.cs
LoggerFactory.cs
LoggerModule.cs
Tuck this whole mess away into a separate class library making it the only piece dependent on Ninject's logging extension and the concrete logger. You can now use MyAppNamespace.ILogger throughout your app, like this:
LoggerTest.cs
somewhere in Main.cs
Main ends up depending on Ninject but not the logging extension and whatever logger you use (the code works with Log4Net, you will need to tweak a bit for NLog). Other parts of the app depend on MyAppNamespace.ILogger. That's about it.
根据官方问题跟踪器,此问题已在版本中修复Ninject.Extensions.Logging 的 3.0.2,因此更新该库将解决该问题。
According to official issue tracker, this was fixed in version 3.0.2 of Ninject.Extensions.Logging, so updating that library will solve the issue.