log4net自定义appender依赖

时间:2015-06-11 21:10:40

标签: c# dependency-injection log4net

我要实现一个log4net自定义appender。 我的appender工作正常但在重构期间我想要隔离责任,所以我需要注入一个接口。 我写了一些代码,你可以理解

namespace WebServiceLogger.Interfaces
{
    public interface IClientService
    {
        void SendLog(string logToSend);
    }
}

这是我的Appender现在通过邮件发送日志,但是 明天我想使用相同的appender将日志发送到Web服务。

using log4net.Appender;
using log4net.Core;
using WebServiceLogger.Interfaces;

namespace WebServiceLogger
{
    public class WebServiceLogAppender : AppenderSkeleton
    {
        private IClientService _clientService;

        //Url property is declared with tag in my log4net.config tag
        public string Url { get; set; }     
        public WebServiceLogAppender()
        {
            InitializeClientService(); 
        }

        protected override void Append(LoggingEvent loggingEvent)
        {
            var log = RenderLoggingEvent(loggingEvent);
            _clientService.SendLog(log);
        }

        private void InitializeClientService()
        {
            var smtpClientFactory = new SmtpClientFactory();
            var mailMessageFactory = new MailMessageFactory();
            _clientService = new EmailClientService(smtpClientFactory,mailMessageFactory)
        }
    }
}

一个实现IClientService的类

using System.Net.Mail;
using WebServiceLogger.Interfaces;

namespace WebServiceLogger
{
    public class EmailClientService : IClientService
    {
        private readonly SmtpClient _smtpClient;
        private readonly IMailMessageFactory _mailMessageFactory;

        public EmailClientService(ISmtpClientFactory smtpClientFactory, IMailMessageFactory mailMessageFactory)
        {
            _smtpClient = smtpClientFactory.Create("username", "password");
            _mailMessageFactory = mailMessageFactory;
        }

        public void SendLog(string logToSend)
        {
            var message = _mailMessageFactory.CreateMailMessage(logToSend);
            _smtpClient.Send(message);
        }
    }
}

我不想在这个类中使用web服务,但我只有一个无参数构造函数。

答案是,我可以在log4net.config中指定一个实现IClientService接口的类的对象吗?

2 个答案:

答案 0 :(得分:3)

因为log4net本身创建了appender,所以不可能使用构造函数或属性注入,并且你不能在config中指定一个类:如果你真的只想指定实现{ <1}}在配置中并在运行时创建它,但这不是真的可取。

如果您的目的是减少代码重复,那么为自定义记录器创建基类将会这样做:然后您可以混合和匹配配置文件中的appender。

IClientService

答案 1 :(得分:0)

不确定您使用的是哪个容器。就我而言,我使用的是Unity,并且能够在创建后通过容器运行appender实例:

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类中的injection属性:

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

    ...
}