我知道这是一个老问题,但我只是想添加一个替代解决方案,以防有人遇到同样的问题。我在没有添加任何绑定重定向并且没有引用两个版本的 log4net 的情况下解决了它。
首先确保卸载以下软件包(后者对 log4net 1.2.10 有硬依赖,我们希望使用最新的 log4net 版本):
Uninstall-Package Castle.Windsor-log4net
Uninstall-Package Castle.Core-log4net
确保您已安装 LoggingFacility 和 log4net(将 log4net 版本替换为所需版本):
Install-Package Castle.LoggingFacility
Install-Package log4net -Version 1.2.13
实现 AbstractLoggerFactory:
public class Log4NetFactory : Castle.Core.Logging.AbstractLoggerFactory
{
internal const string DefaultConfigFileName = "log4net.config";
public Log4NetFactory()
: this(DefaultConfigFileName)
{
}
public Log4NetFactory(string configFile)
{
var file = GetConfigFile(configFile);
XmlConfigurator.ConfigureAndWatch(file);
}
public Log4NetFactory(bool configuredExternally)
{
if (configuredExternally)
{
return;
}
var file = GetConfigFile(DefaultConfigFileName);
XmlConfigurator.ConfigureAndWatch(file);
}
public Log4NetFactory(Stream config)
{
XmlConfigurator.Configure(config);
}
public override ILogger Create(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
var log = LogManager.GetLogger(type);
return new Log4netLogger(log, this);
}
public override ILogger Create(Type type, LoggerLevel level)
{
throw new NotSupportedException("Logger levels cannot be set at runtime. Please review your configuration file.");
}
public override ILogger Create(string name)
{
if (name == null)
throw new ArgumentNullException("name");
var log = LogManager.GetLogger(name);
return new Log4netLogger(log, this);
}
public override ILogger Create(string name, LoggerLevel level)
{
throw new NotSupportedException("Logger levels cannot be set at runtime. Please review your configuration file.");
}
}
实现 ILogger 接口:
[Serializable]
public class Log4netLogger : MarshalByRefObject, Castle.Core.Logging.ILogger
{
private static readonly Type DeclaringType = typeof(Log4netLogger);
public Log4netLogger(ILogger logger, Log4NetFactory factory)
{
Logger = logger;
Factory = factory;
}
internal Log4netLogger()
{
}
internal Log4netLogger(ILog log, Log4NetFactory factory)
: this(log.Logger, factory)
{
}
public bool IsDebugEnabled
{
get { return Logger.IsEnabledFor(Level.Debug); }
}
public bool IsErrorEnabled
{
get { return Logger.IsEnabledFor(Level.Error); }
}
public bool IsFatalEnabled
{
get { return Logger.IsEnabledFor(Level.Fatal); }
}
public bool IsInfoEnabled
{
get { return Logger.IsEnabledFor(Level.Info); }
}
public bool IsWarnEnabled
{
get { return Logger.IsEnabledFor(Level.Warn); }
}
protected internal Log4NetFactory Factory { get; set; }
protected internal ILogger Logger { get; set; }
public override string ToString()
{
return Logger.ToString();
}
public virtual Castle.Core.Logging.ILogger CreateChildLogger(string name)
{
return Factory.Create(Logger.Name + "." + name);
}
public void Debug(string message)
{
if (IsDebugEnabled)
{
Logger.Log(DeclaringType, Level.Debug, message, null);
}
}
public void Debug(Func<string> messageFactory)
{
if (IsDebugEnabled)
{
Logger.Log(DeclaringType, Level.Debug, messageFactory.Invoke(), null);
}
}
public void Debug(string message, Exception exception)
{
if (IsDebugEnabled)
{
Logger.Log(DeclaringType, Level.Debug, message, exception);
}
}
public void DebugFormat(string format, params Object[] args)
{
if (IsDebugEnabled)
{
Logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void DebugFormat(Exception exception, string format, params Object[] args)
{
if (IsDebugEnabled)
{
Logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void DebugFormat(IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsDebugEnabled)
{
Logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void DebugFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsDebugEnabled)
{
Logger.Log(DeclaringType, Level.Debug, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Error(string message)
{
if (IsErrorEnabled)
{
Logger.Log(DeclaringType, Level.Error, message, null);
}
}
public void Error(Func<string> messageFactory)
{
if (IsErrorEnabled)
{
Logger.Log(DeclaringType, Level.Error, messageFactory.Invoke(), null);
}
}
public void Error(string message, Exception exception)
{
if (IsErrorEnabled)
{
Logger.Log(DeclaringType, Level.Error, message, exception);
}
}
public void ErrorFormat(string format, params Object[] args)
{
if (IsErrorEnabled)
{
Logger.Log(DeclaringType, Level.Error, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void ErrorFormat(Exception exception, string format, params Object[] args)
{
if (IsErrorEnabled)
{
Logger.Log(DeclaringType, Level.Error, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void ErrorFormat(IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsErrorEnabled)
{
Logger.Log(DeclaringType, Level.Error, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void ErrorFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsErrorEnabled)
{
Logger.Log(DeclaringType, Level.Error, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Fatal(string message)
{
if (IsFatalEnabled)
{
Logger.Log(DeclaringType, Level.Fatal, message, null);
}
}
public void Fatal(Func<string> messageFactory)
{
if (IsFatalEnabled)
{
Logger.Log(DeclaringType, Level.Fatal, messageFactory.Invoke(), null);
}
}
public void Fatal(string message, Exception exception)
{
if (IsFatalEnabled)
{
Logger.Log(DeclaringType, Level.Fatal, message, exception);
}
}
public void FatalFormat(string format, params Object[] args)
{
if (IsFatalEnabled)
{
Logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void FatalFormat(Exception exception, string format, params Object[] args)
{
if (IsFatalEnabled)
{
Logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void FatalFormat(IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsFatalEnabled)
{
Logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void FatalFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsFatalEnabled)
{
Logger.Log(DeclaringType, Level.Fatal, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Info(string message)
{
if (IsInfoEnabled)
{
Logger.Log(DeclaringType, Level.Info, message, null);
}
}
public void Info(Func<string> messageFactory)
{
if (IsInfoEnabled)
{
Logger.Log(DeclaringType, Level.Info, messageFactory.Invoke(), null);
}
}
public void Info(string message, Exception exception)
{
if (IsInfoEnabled)
{
Logger.Log(DeclaringType, Level.Info, message, exception);
}
}
public void InfoFormat(string format, params Object[] args)
{
if (IsInfoEnabled)
{
Logger.Log(DeclaringType, Level.Info, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void InfoFormat(Exception exception, string format, params Object[] args)
{
if (IsInfoEnabled)
{
Logger.Log(DeclaringType, Level.Info, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void InfoFormat(IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsInfoEnabled)
{
Logger.Log(DeclaringType, Level.Info, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void InfoFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsInfoEnabled)
{
Logger.Log(DeclaringType, Level.Info, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Warn(string message)
{
if (IsWarnEnabled)
{
Logger.Log(DeclaringType, Level.Warn, message, null);
}
}
public void Warn(Func<string> messageFactory)
{
if (IsWarnEnabled)
{
Logger.Log(DeclaringType, Level.Warn, messageFactory.Invoke(), null);
}
}
public void Warn(string message, Exception exception)
{
if (IsWarnEnabled)
{
Logger.Log(DeclaringType, Level.Warn, message, exception);
}
}
public void WarnFormat(string format, params Object[] args)
{
if (IsWarnEnabled)
{
Logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void WarnFormat(Exception exception, string format, params Object[] args)
{
if (IsWarnEnabled)
{
Logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void WarnFormat(IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsWarnEnabled)
{
Logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void WarnFormat(Exception exception, IFormatProvider formatProvider, string format, params Object[] args)
{
if (IsWarnEnabled)
{
Logger.Log(DeclaringType, Level.Warn, new SystemStringFormat(formatProvider, format, args), exception);
}
}
}
在 WindsorInstaller 中注册自定义 Log4NetFactory:
public class LoggerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<LoggingFacility>(x =>
x.WithConfig(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)
.ToLog("MyLogger")
.LogUsing<Log4NetFactory>());
}
}
将通常的 log4net 配置添加到您的 app/web.config - 如果还没有的话。
确保 log4net 配置中存在“MyLogger”,例如
<logger name="MyLogger" additivity="false">
<level value="DEBUG" />
<appender-ref ref="MyAppender" />
</logger>
现在您可以像这样注入 ILogger:
public class MyClass
{
public MyClass(ILogger logger)
{
logger.Info("Castle Windsor with newest log4net.");
}
}
使用上述方法,您可以将任何版本的 log4net 与 Castle Windsor 一起使用。我有 log4net 1.2.13 与 Castle Windsor 3.3.3 一起使用。