在自定义Log4Net附加程序中使用IoC [英] Using IoC in a custom Log4Net appender

查看:105
本文介绍了在自定义Log4Net附加程序中使用IoC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不幸的是,当我用Log4Net搜索涉及Unity或IoC的任何内容时,我已经搜索了很长时间,我得到的唯一结果就是如何通过IoC自动填充ILog.这不是我要做的不是.

I have searched quite a while unfortunately when I search for anything involving Unity or IoC with Log4Net the only results I get is how to make ILog automatically populated via IoC. This is not what I am trying to do.

我有一个自定义的Appender,可通过WCF将数据传输到服务器.我想做的是传入一种工厂方法,最好是由Unity生成的一种方法,该方法为我创建WCF客户端类,这样我就可以在单元测试期间将实际的客户端类换成存根.问题是我无法在任何地方找到有关如何将参数传递到自定义log4net附加程序中的任何解释.

I have a custom Appender that transmits data over WCF to a server. What I would like to do is pass in a factory method, preferably one generated by Unity, that creates the WCF client class for me so I can swap out the real client class for stubs during unit testing. The problem is I can not find any explanation anywhere on how to pass a argument in to a custom log4net appender.

这是我通常使用Unity来实现的方式.

Here is how I would normally implement this using 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>(),它是在log4net库中调用new WcfAppender()的.如何告诉log4net库改用new WcfAppender(factoryGeneratedFromUnity)?

However I don't call container.Resolve<WcfAppender>() it is in the log4net library that new WcfAppender() gets called. How do I tell the log4net library to use new WcfAppender(factoryGeneratedFromUnity) instead?

推荐答案

创建后,我能够通过Unity容器运行附加器实例:

I was able to run the appender instance through Unity container after its creation:

ILog logger = LogManager.GetLogger("My Logger");
IAppender[] appenders = logger.Logger.Repository.GetAppenders();
foreach (IAppender appender in appenders)
{
    container.BuildUp(appender.GetType(), appender);
}

container.RegisterInstance(logger);

BuildUp()方法将在appender类中填充注入属性:

BuildUp() method will populate the injection property in the appender class:

public class LogDatabaseSaverAppender : AppenderSkeleton
{
    [Dependency]
    public IContextCreator ContextCreator { get; set; }

    ...
}

这篇关于在自定义Log4Net附加程序中使用IoC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆