I know this is an old question, but I just wanted to add an alternative solution, in case anyone is struggling with the same issue. I solved it without adding any binding redirects and without referencing two versions of log4net.
First make sure to uninstall the following packages (the latter has a hard dependency on log4net 1.2.10 and we want to use the newest log4net version):
Uninstall-Package Castle.Windsor-log4net
Uninstall-Package Castle.Core-log4net
Make sure you have the LoggingFacility and log4net installed (replace the log4net version with the desired version):
Install-Package Castle.LoggingFacility
Install-Package log4net -Version 1.2.13
Implement the 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.");
}
}
Implement the ILogger interface:
[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);
}
}
}
Register the custom Log4NetFactory in a WindsorInstaller:
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>());
}
}
Add the usual log4net configuration to your app/web.config - if not already there.
Make sure that "MyLogger" exists in the log4net configuration, e.g.
<logger name="MyLogger" additivity="false">
<level value="DEBUG" />
<appender-ref ref="MyAppender" />
</logger>
Now you can have the ILogger injected like this:
public class MyClass
{
public MyClass(ILogger logger)
{
logger.Info("Castle Windsor with newest log4net.");
}
}
Using the above method you can use any version of log4net together with Castle Windsor. I have log4net 1.2.13 working with Castle Windsor 3.3.3.