我要实现一个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接口的类的对象吗?
答案 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; }
...
}