意外行为Log4NetExtension与Unity容器中已注册的IEnumerable <t>结合使用

时间:2019-03-19 14:21:04

标签: c# unity-container

我正在使用 log4net 作为日志记录框架,并使用 Unity 作为我的IoC容器。接下来,我安装了 Unity.log4net nuget软件包。当我开始使用命名注册时,记录器名称出现问题。我使用命名注册启用T的IEnumerable的构造函数注入。

下面的代码是一个非常简单的程序,它显示了我的问题。

using Container.Activities;
using log4net;
using Unity;
using Unity.log4net;

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

namespace Container
{
    class Program
    {
        static void Main(string[] args)
        {
            UnityContainer container = new UnityContainer();
            container.AddNewExtension<Log4NetExtension>();

            container.RegisterType<IActivity, ActivityA>(nameof(ActivityA));
            container.RegisterType<IActivity, ActivityB>(nameof(ActivityB));
            container.RegisterType<IActivityExecutor, ActivityExecutor>();

            var logger = LogManager.GetLogger("Test application");
            logger.Info("Application started.");

            container.Resolve<IActivityExecutor>().Execute();

            logger.Info("Application stopped.");
        }
    }
}

我创建了一个Activity接口,并将对该接口进行多种实现。

namespace Container.Activities
{
    public interface IActivity
    {
        void Execute();
    }
}

在此示例中,我只有两个实现,即活动A和B。这两个实现都需要将log4net.ILog实现注入到构造函数中。

using log4net;

namespace Container.Activities
{
    public class ActivityA : IActivity
    {
        private readonly ILog _logger;

        public ActivityA(ILog logger)
        {
            _logger = logger;
        }

        public void Execute()
        {
            _logger.Info($"Hello, I am {nameof(ActivityA)}.");
        }
    }
}

活动B:

using log4net;

namespace Container.Activities
{
    public class ActivityB : IActivity
    {
        private readonly ILog _logger;

        public ActivityB(ILog logger)
        {
            _logger = logger;
        }

        public void Execute()
        {
            _logger.Info($"Hello, I am {nameof(ActivityB)}.");
        }
    }
}

在多个IActivity实例旁边,我有一个IActivityExecutor接口。

namespace Container.Activities
{
    public interface IActivityExecutor
    {
        void Execute();
    }
}

Activity Executor实例应执行所有已注册的IActivity实例。接下来,它注入了自己的ILog实例,因此它也可以写入日志文件。

using log4net;
using System.Collections.Generic;
using System.Linq;

namespace Container.Activities
{
    public class ActivityExecutor : IActivityExecutor
    {
        private readonly ILog _logger;
        private readonly IEnumerable<IActivity> _activities;

        public ActivityExecutor(ILog logger, IEnumerable<IActivity> activities)
        {
            _logger = logger;
            _activities = activities;
        }

        public void Execute()
        {
            _logger.Info($"About to process {_activities.Count()}.");

            foreach (var activity in _activities)
            {
                activity.Execute();
            }
        }
    }
}

我的日志文件中的输出如下所示。请注意,ActivityA和ActivityB都以记录器名称ActivityExecutor结尾在日志文件中。

2019-03-19 14:43 [Test application] [1] INFO - Application started.
2019-03-19 14:43 [Container.Activities.ActivityExecutor] [1] INFO - About to process 2.
2019-03-19 14:43 [Container.Activities.ActivityExecutor] [1] INFO - Hello, I am ActivityA.
2019-03-19 14:43 [Container.Activities.ActivityExecutor] [1] INFO - Hello, I am ActivityB.
2019-03-19 14:43 [Test application] [1] INFO - Application stopped.

此输出不是我期望的。我希望看到下面的日志。因此,每个活动都使用自己的名称进行记录。

2019-03-19 14:43 [Test application] [1] INFO - Application started.
2019-03-19 14:43 [Container.Activities.ActivityExecutor] [1] INFO - About to process 2.
2019-03-19 14:43 [Container.Activities.ActivityA] [1] INFO - Hello, I am ActivityA.
2019-03-19 14:43 [Container.Activities.ActivityB] [1] INFO - Hello, I am ActivityB.
2019-03-19 14:43 [Test application] [1] INFO - Application stopped.

此问题的根本原因似乎与在Unity容器中使用命名注册有关。如果我在ActivityExecutor的构造函数中添加另一个接口参数,并将其放在ILog参数之前,则在日志文件中使用该组件的名称。

我可以从该程序的所有构造函数中删除ILog,而是调用LogManager以获取带有每个组件名称的记录器。但是,我更喜欢在需要时注入ILog接口,并使用Unity.log4net软件包。

_logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

我在这里想念东西吗?

0 个答案:

没有答案
相关问题