不幸的是,当我使用 Log4Net 搜索涉及 Unity 或 IoC 的任何内容时,我已经搜索了很长时间,我得到的唯一结果是如何制作 ILog
通过 IoC 自动填充。这不是我想要做的。
我有一个自定义 Appender,它通过 WCF 将数据传输到服务器。我想做的是传入一个工厂方法,最好是 Unity 生成的方法,它为我创建 WCF 客户端类,这样我就可以在单元测试期间将真正的客户端类换成 stub 。问题是我在任何地方都找不到关于如何将参数传递给自定义 log4net appender 的任何解释。
这是我通常使用 Unity 实现它的方式。
public class WcfAppender : BufferingAppenderSkeleton
{
public WcfAppender(Func<ClientLoggerClient> loggerClientFactory) //How do I get this Func passed in?
{
LoggerClientFactory = loggerClientFactory;
}
private readonly Func<ClientLoggerClient> LoggerClientFactory;
private static readonly ILog Logger = LogManager.GetLogger(typeof(WcfAppender));
private static readonly string LoggerName = typeof(WcfAppender).FullName;
public override void ActivateOptions()
{
base.ActivateOptions();
this.Fix = FixFlags.All;
}
protected override bool FilterEvent(LoggingEvent loggingEvent)
{
if (loggingEvent.LoggerName.Equals(LoggerName))
return false;
else
return base.FilterEvent(loggingEvent);
}
protected override void SendBuffer(LoggingEvent[] events)
{
try
{
var client = LoggerClientFactory();
try
{
client.LogRecord(events.Select(CreateWrapper).ToArray());
}
finally
{
client.CloseConnection();
}
}
catch (Exception ex)
{
Logger.Error("Error sending error log to server", ex);
}
}
private ErrorMessageWrapper CreateWrapper(LoggingEvent arg)
{
var wrapper = new ErrorMessageWrapper();
//(Snip)
return wrapper;
}
}
但是我不叫container.Resolve<WcfAppender>()
new WcfAppender()
在 log4net 库中被调用。我如何告诉 log4net 库使用 new WcfAppender(factoryGeneratedFromUnity)
相反?
最佳答案
我认为samy is right ,这是我如何解决它的实现。
ActivateOptions()
在我初始化我的 Unity 容器之前被调用,所以为了安全起见,我只是将工厂方法的检索放在 SendBuffer
方法中。我最终使用 LogManager.GetRepository().Properties
属性来存储工厂对象。
public class WcfAppender : BufferingAppenderSkeleton
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(WcfAppender));
private static readonly string LoggerName = typeof(WcfAppender).FullName;
public override void ActivateOptions()
{
base.ActivateOptions();
this.Fix = FixFlags.All;
}
protected override bool FilterEvent(LoggingEvent loggingEvent)
{
if (loggingEvent.LoggerName.Equals(LoggerName))
return false;
else
return base.FilterEvent(loggingEvent);
}
protected override void SendBuffer(LoggingEvent[] events)
{
try
{
var clientFactory = log4net.LogManager.GetRepository().Properties["ClientLoggerFactory"] as Func<ClientLoggerClient>;
if (clientFactory != null)
{
var client = clientFactory();
try
{
client.LogRecord(events.Select(CreateWrapper).ToArray());
}
finally
{
client.CloseConnection();
}
}
}
catch (Exception ex)
{
Logger.Error("Error sending error log to server", ex);
}
}
private ErrorMessageWrapper CreateWrapper(LoggingEvent arg)
{
var wrapper = new ErrorMessageWrapper();
//SNIP...
return wrapper;
}
}
然后我创建工厂并在我的程序启动期间存储它。
static class Program
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
log4net.Util.SystemInfo.NullText = String.Empty;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Logger.Debug("Service Starting");
using (var container = new UnityContainer())
{
var debugMode = args.Contains("--debug", StringComparer.InvariantCultureIgnoreCase);
BaseUnityConfiguration.Configure(container, debugMode);
LogManager.GetRepository().Properties["ClientLoggerFactory"] = container.Resolve<Func<ClientLoggerClient>>();
//...
关于c# - 在自定义 Log4Net appender 中使用 IoC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23634472/