log4net自定义追加程序依赖项 [英] log4net custom appender dependency
问题描述
我将实现一个log4net自定义附加程序. 我的附加程序工作正常,但是在重构期间,我想隔离职责,因此我需要注入一个接口. 我写了一些代码,以便您了解
I'm going to implement a log4net custom appender. My appender work fine but during refactory i want isolate the responsability, so i need to inject one interface. I write some code so you can understand
namespace WebServiceLogger.Interfaces
{
public interface IClientService
{
void SendLog(string logToSend);
}
}
这是我的Appender,现在通过邮件发送日志,但是 明天我要使用相同的附加程序将日志发送到Web服务.
This is my Appender that now send log by mail, but tomorrow i want use the same appender for send log to a web service.
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的类
And one class that implement 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服务,但是我只有一个无参数的构造函数.
I don't want cable the webservice inside this class but i have only a parameterless constructor.
答案是,我可以在log4net.config中指定实现IClientService接口的一个类的对象吗?
The answer is , can i specify the object of one class that implement the IClientService interface in log4net.config ?
推荐答案
由于log4net会自行创建附加程序,因此无法使用构造函数或属性注入,并且无法在config中指定类:如果可以,我真的只想在配置中指定实现IClientService
的类的名称,然后在运行时创建它,但这并不可取.
Because log4net creates the appenders itself, it isn't possible to use constructor or property injection, and you cannot specify a class in the config: you could if you really wanted to just specify the name of the class implementing IClientService
in the config and create it at runtime, but that's not really advisable.
如果您打算减少代码重复,那么为您的自定义记录器创建一个基类将做到这一点:然后您可以在配置文件中混合并匹配附加器.
If your intention is to reduce code duplication, then creating a base class for your custom logger will do that: then you can mix and match the appenders in your config file.
public abstract class BaseWebServiceLogAppender : AppenderSkeleton
{
protected IClientService _clientService;
//Url property is declared with tag in my log4net.config tag
public string Url { get; set; }
public BaseWebServiceLogAppender()
{
InitializeClientService();
}
protected override void Append(LoggingEvent loggingEvent)
{
var log = RenderLoggingEvent(loggingEvent);
_clientService.SendLog(log);
}
protected abstract void InitializeClientService();
}
public class EmailWebServiceLogAppender : BaseWebServiceLogAppender
{
protected override void InitializeClientService()
{
var smtpClientFactory = new SmtpClientFactory();
var mailMessageFactory = new MailMessageFactory();
_clientService = new EmailClientService(smtpClientFactory,mailMessageFactory)
}
}
public class SmsWebServiceLogAppender : BaseWebServiceLogAppender
{
protected override void InitializeClientService()
{
_clientService = new SmSClientService(…);
}
}
这篇关于log4net自定义追加程序依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!