moo*_*aka 6 log4net ninject-2 ninject-extensions nuget-package c#-4.0
我通过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");
Run Code Online (Sandbox Code Playgroud)
结果是:
2011-08-29 10:02:02,071 [9] DEBUG Log4NetLoggerTest foo { bar
Run Code Online (Sandbox Code Playgroud)
但是,当通过Ninject访问记录器时:
using (IKernel kernel = new StandardKernel())
{
var ninjectLogger = kernel.Get<NinjectLoggerTest>();
ninjectLogger.Log.Debug("foo { bar");
}
Run Code Online (Sandbox Code Playgroud)
NinjectLoggerTest就是这样的:
using Ninject.Extensions.Logging;
namespace TestApp
{
public class NinjectLoggerTest
{
public NinjectLoggerTest(ILogger log)
{
Log = log;
}
public ILogger Log;
}
}
Run Code Online (Sandbox Code Playgroud)
出乎意料的是,结果是:
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>
Run Code Online (Sandbox Code Playgroud)
更糟糕的是,当使用ILogger的Trace方法时,mscorlib.dll中存在类型'System.FormatException'的第一次机会异常
难道我做错了什么?我该如何解决这个问题?
TIA
解决方案是创建一个简单的记录器外观,以完全将Ninject与应用程序的其余部分分离.步骤是:
1)将Ninject的ILogger接口复制/粘贴到应用程序的命名空间中(不仅仅是继承,或者你最终取决于Ninject的程序集,因为通过Ninject的ILogger公开了类型).
2)创建自定义Logger,LoggerFactory和LoggerModule类.
3)将LoggerModule传递给Ninject的StandardKernel
为了完整性,代码是:
Ninject的ILogger - 复制/粘贴ILogger接口,将其命名空间更改为MyAppNamespace.Logger并添加以下方法:
void Debug(string message);
void Info(string message);
void Trace(string message);
void Warn(string message);
void Error(string message);
void Fatal(string message);
Run Code Online (Sandbox Code Playgroud)
Logger.cs
namespace MyAppNamespace.Logger
{
using System;
class Logger : Ninject.Extensions.Logging.Log4net.Infrastructure.Log4NetLogger, ILogger
{
private const string DumpVerbatimFormat = "{0}";
public Logger(Type type)
: base(type)
{
}
public void Debug(string message)
{
base.Debug(DumpVerbatimFormat, message);
}
public void Info(string message)
{
base.Info(DumpVerbatimFormat, message);
}
public void Trace(string message)
{
base.Trace(DumpVerbatimFormat, message);
}
public void Warn(string message)
{
base.Warn(DumpVerbatimFormat, message);
}
public void Error(string message)
{
base.Error(DumpVerbatimFormat, message);
}
public void Fatal(string message)
{
base.Fatal(DumpVerbatimFormat, message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
LoggerFactory.cs
namespace MyAppNamespace.Logger
{
using System;
using System.Collections.Generic;
static class LoggerFactory
{
public static ILogger GetLogger(Ninject.Activation.IContext context)
{
return GetLogger(context.Request.Target == null ? typeof(ILogger) : context.Request.Target.Member.DeclaringType);
}
private static readonly Dictionary<Type, ILogger> TypeToLoggerMap = new Dictionary<Type, ILogger>();
private static ILogger GetLogger(Type type)
{
lock (TypeToLoggerMap)
{
if (TypeToLoggerMap.ContainsKey(type))
return TypeToLoggerMap[type];
ILogger logger = new Logger(type);
TypeToLoggerMap.Add(type, logger);
return logger;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
LoggerModule.cs
namespace MyAppNamespace.Logger
{
public class LoggerModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
log4net.Config.XmlConfigurator.Configure();
Bind<ILogger>().ToMethod(LoggerFactory.GetLogger);
}
}
}
Run Code Online (Sandbox Code Playgroud)
将整个混乱放入一个单独的类库中,使其成为唯一依赖于Ninject的日志记录扩展和具体记录器的部分.您现在可以在整个应用中使用MyAppNamespace.ILogger,如下所示:
LoggerTest.cs
namespace MyAppNamespace.Whatever
{
using Logger;
public class LoggerTest
{
public LoggerTest(ILogger log)
{
Log.Info("Logger starting up");
}
}
}
Run Code Online (Sandbox Code Playgroud)
Main.cs中的某个地方
using (IKernel kernel = new StandardKernel(new Logger.LoggerModule()))
{
kernel.Get<LoggerTest>();
}
Run Code Online (Sandbox Code Playgroud)
Main取决于Ninject而不是日志记录扩展和你使用的任何记录器(代码适用于Log4Net,你需要为NLog调整一下).该应用程序的其他部分依赖于MyAppNamespace.ILogger.就是这样.
| 归档时间: |
|
| 查看次数: |
4178 次 |
| 最近记录: |