【问题标题】:Log4Net XML config requires ILoggerRepositoryLog4Net XML 配置需要 ILoggerRepository
【发布时间】:2020-07-16 02:43:38
【问题描述】:

我正在构建一个 C# 控制台应用程序,并且正在使用 Autofac 和 log4net。我按照 Autofac 的指南添加了一个 log4net 模块,但是我在配置我的日志时遇到了一些困难。问题是当我尝试创建 XMLConfiguration 时,编译器要求我提供ILoggerRepository,我不知道那是什么。我查看了 log4net 文档,但在此上下文中未提及存储库。

这是我的模块:

using System.Reflection;
using log4net;
using Autofac.Core;
using Autofac.Core.Registration;
using System.Linq;
using log4net.Config;
using System.IO;

namespace Logging
{
    public class LoggingModule : Autofac.Module
    {
        public LoggingModule()
        {
            // The error happens here!
            XmlConfigurator.Configure(new FileInfo("log4net.xml"));
        }

        private static void InjectLoggerProperties(object instance)
        {
            var instanceType = instance.GetType();

            // Get all the injectable properties to set.
            // If you wanted to ensure the properties were only UNSET properties,
            // here's where you'd do it.
            var properties = instanceType
              .GetProperties(BindingFlags.Public | BindingFlags.Instance)
              .Where(p => p.PropertyType == typeof(ILog) && p.CanWrite && p.GetIndexParameters().Length == 0);

            // Set the properties located.
            foreach (var propToSet in properties)
            {
                propToSet.SetValue(instance, LogManager.GetLogger(instanceType), null);
            }
        }

        private static void OnComponentPreparing(object sender, PreparingEventArgs e)
        {
            e.Parameters = e.Parameters.Union(
              new[]
              {
        new ResolvedParameter(
            (p, i) => p.ParameterType == typeof(ILog),
            (p, i) => LogManager.GetLogger(p.Member.DeclaringType)
        ),
              });
        }

        protected override void AttachToComponentRegistration(IComponentRegistryBuilder componentRegistryBuilder, IComponentRegistration registration)
        {
            // Handle constructor parameters.
            registration.Preparing += OnComponentPreparing;

            // Handle properties.
            registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
        }
    }
}

编译错误发生在这里:XmlConfigurator.Configure(new FileInfo("log4net.xml")); 它说:

Severity    Code    Description Project File    Line    Suppression State
Error   CS1503  Argument 1: cannot convert from 'System.IO.FileInfo' to 'log4net.Repository.ILoggerRepository'  MyApp   C:\Dev\MyApp\Logging\LoggingModule.cs   15  Active

【问题讨论】:

  • 你能检查XmlConfigurator的命名空间吗?看起来类 XmlConfigurator 不是从 log4net 使用的。尝试接线log4net.XmlConfigurator.Configure(new FileInfo("log4net.xml"));
  • 嗨,我认为我使用了正确的类。我已将代码更改为:log4net.Config.XmlConfigurator.Configure(new FileInfo("log4net.xml"));,但错误仍然存​​在。

标签: c# log4net autofac


【解决方案1】:

我已经通过this question 的回答解决了我的问题。

这是我添加ILoggerRepository 并添加到配置中的方式:

ILoggerRepository repository = log4net.LogManager.GetRepository(Assembly.GetCallingAssembly());
log4net.Config.XmlConfigurator.Configure(repository, new FileInfo("log4net.xml"));

这是我的完整工作代码:

using System.Reflection;
using log4net;
using Autofac.Core;
using Autofac.Core.Registration;
using System.Linq;
using log4net.Config;
using System.IO;
using log4net.Repository;

namespace Logging
{
    public class LoggingModule : Autofac.Module
    {
        public LoggingModule()
        {
            ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly());
            XmlConfigurator.Configure(repository, new FileInfo("log4net.xml"));
        }

        private static void InjectLoggerProperties(object instance)
        {
            var instanceType = instance.GetType();

            // Get all the injectable properties to set.
            // If you wanted to ensure the properties were only UNSET properties,
            // here's where you'd do it.
            var properties = instanceType
              .GetProperties(BindingFlags.Public | BindingFlags.Instance)
              .Where(p => p.PropertyType == typeof(ILog) && p.CanWrite && p.GetIndexParameters().Length == 0);

            // Set the properties located.
            foreach (var propToSet in properties)
            {
                propToSet.SetValue(instance, LogManager.GetLogger(instanceType), null);
            }
        }

        private static void OnComponentPreparing(object sender, PreparingEventArgs e)
        {
            e.Parameters = e.Parameters.Union(
              new[]
              {
        new ResolvedParameter(
            (p, i) => p.ParameterType == typeof(ILog),
            (p, i) => LogManager.GetLogger(p.Member.DeclaringType)
        ),
              });
        }

        protected override void AttachToComponentRegistration(IComponentRegistryBuilder componentRegistryBuilder, IComponentRegistration registration)
        {
            // Handle constructor parameters.
            registration.Preparing += OnComponentPreparing;

            // Handle properties.
            registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2015-07-21
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多