log4net 自定义追加器依赖项
本文关键字:依赖 追加 自定义 log4net | 更新日期: 2023-09-27 17:55:39
我要实现一个log4net自定义追加器。我的追加器工作正常,但在重新制造期间,我想隔离责任,所以我需要注入一个接口。我写了一些代码,以便您理解
namespace WebServiceLogger.Interfaces
{
public interface IClientService
{
void SendLog(string logToSend);
}
}
这是我的追加器,现在通过邮件发送日志,但是明天我想使用相同的追加器将日志发送到 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接口的类的对象吗?
因为 log4net 自己创建追加器,所以无法使用构造函数或属性注入,也不能在配置中指定类:如果你真的想在配置中指定实现IClientService
的类的名称并在运行时创建它,你可以这样做,但这并不可取。
如果您的目的是减少代码重复,那么为自定义记录器创建一个基类就可以做到这一点:然后,您可以混合和匹配配置文件中的追加器。
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(…);
}
}
不确定您使用的是哪个容器。就我而言,我使用的是 Unity,并且能够在创建容器后通过容器运行追加器实例:
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()
方法将填充追加器类中的注入属性:
public class LogDatabaseSaverAppender : AppenderSkeleton
{
[Dependency]
public IContextCreator ContextCreator { get; set; }
...
}