使用 Log4Net 模块旁边的 Autofac 注册 Log4Net 命名记录器

Registering Log4Net Named Logger with Autofac next to Log4Net Module

目前我正在使用 Log4Net 模块通过 AutoFac 注册我的记录器实例:

containerBuilder.RegisterModule(new Log4NetModule());

这工作得很好,但是,现在我需要能够将某些日志记录行写入一个单独的文件。显然我希望这是可注射的,所以我想按如下方式进行:

接口:

public interface IStatisticsLogger : ILog
{ }

Autofac 注册:

containerBuilder.RegisterInstance(LogManager.GetLogger("Statistics"))
   .As<IStatisticsLogger>();

Log4Net 配置:

<logger name="Statistics" additivity="false">
  <level value="ALL" />
  <appender-ref ref="StatisticsFileAppender" />
</logger>

<appender name="StatisticsFileAppender" type="log4net.Appender.RollingFileAppender">
      <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="DEBUG" />
        <levelMax value="FATAL" />
      </filter>
      <file type="log4net.Util.PatternString" value="Logs\Statistics.txt"/>
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="1000KB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date,%message%newline" />
      </layout>
</appender>

Class:

public Service(ILog logging, IStatisticsLogger statisticsLogger)
{
   // logging = General logging
   // statisticsLogger = Log to a specific file
   ...
}

但是,当我 运行 这样做时,我收到以下错误:

类型 log4net.Core.LogImpl 无法分配给服务 IStatisticsLogger

关于如何实现我的目标有什么想法吗?

通过

containerBuilder.RegisterInstance(LogManager.GetLogger("Statistics"))
                .As<IStatisticsLogger>();

你告诉 AutofacLogManager.GetLogger("Statistics") 的 return 转换为 ILogIStatisticsLogger。这是无效的,因为 ILog 不是 IStatisticsLogger

为了使用IStatisticsLogger接口,你应该有一个这样的接口的实现。

public class StatisticsLogger : IStatisticsLogger 
{
    public StatisticsLogger(ILog logger)
    {
            this._logger =  logger; 
    }
    private readonly ILog _logger; 

    // implements ILog 
    public virtual void Info(Object message)
    {
        this._logger.info(message); 
    }

    // etc. 
}

然后,你就可以在Autofac中注册这个类型了:

containerBuilder.RegisterType<StatisticsLogger>()
                .WithParameter("logger", LogManager.GetLogger("Statistics"))
                .As<IStatisticsLogger>();

实施 ILog 很无聊。您可以依赖 log4net 的默认实现。

public class StatisticsLogger : LogImpl, IStatisticsLogger
{
    public StatisticsLogger(ILogger logger) : base(logger)
    { }
}

注册将是这样的:

containerBuilder.RegisterType<StatisticsLogger>()
                .WithParameter("logger", LogManager.GetLogger("Statistics").Logger)
                .As<IStatisticsLogger>();