程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Microsoft.Practices.Unity 給不同的對象注入不同的Logger,microsoft.practices

Microsoft.Practices.Unity 給不同的對象注入不同的Logger,microsoft.practices

編輯:C#入門知識

Microsoft.Practices.Unity 給不同的對象注入不同的Logger,microsoft.practices


場景:我們做項目的時候常常會引用第三方日志框架來幫助我們記錄日志,日志組件的用途主要是審計、跟蹤、和調試。就說我最常用的日志組件log4net吧,這個在.NET同行當中應該算是用得非常多的一個日志組件了。

而同時,我們又經常使用IoC技術,來降低我們項目之間、模塊之間的耦合度,比如我現在在用的Microsoft.Practices.Unity(當然Autofac也是非常好用的)。

我們很清楚的知道log4net的優點,配置非常簡單又非常完善,它能提供不同的日志級別、記錄器、組織形式……

比如說 :

var log = LogManager.GetLogger("User");

但是當我們使用IoC注入日志記錄器對象的時候,就犯難了,我想給不同的類注入不同的日志記錄器,這樣方便我選擇性的配置哪些類、哪些級別的日志需要輸出。

如:

    public class UserService
    {
        public UserRepository Repository { get; }
        public ILog Log { get; set; }

        public UserService(UserRepository repository,ILog log)
        {
            Repository = repository;
            Log = log;
        }
    }

    public class UserRepository
    {
        public ILog Log { get; }

        public UserRepository(ILog log)
        {
            Log = log;
        }
    }

我想要的是給UserRepository注入 LogManager.GetLogger(typeof(UserRepository));
我想要的是給UserService注入 LogManager.GetLogger(typeof(UserService));

這樣在UserRepository、UserService中寫日志的時候,是分別寫入不同的日志記錄器,我可以很方便的控制收集哪些日志。

該怎麼做呢?

 

找了很多資料,都沒有找到Microsoft.Practices.Unity如何訪問解析依賴時的上下文,我希望上下文中能找到請求ILog的對象是什麼類型。

終於還是在Microsoft.Practices.Unity的源代碼討論區裡面找到了解決方案,遂封裝一下,簡化類似操作。測試代碼如下:

using NUnit.Framework;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using log4net;

namespace Microsoft.Practices.Unity.Tracking.Tests
{
    [TestFixture]
    public class TrackingInjectionFactoryTests
    {
        public IUnityContainer Container { get; set; }
        [SetUp]
        public void Initialize()
        {
            Trace.Listeners.Add(new ConsoleTraceListener());
            Container = new UnityContainer();
            Container.Tracking();
            Container.RegisterType<UserService>();
            Container.RegisterType<ILog>(new TrackingInjectionFactory((container, context, policy) => LogManager.GetLogger(policy.RequestType?.Name ?? "null")));
        }

        [Test]
        public void TrackingInjectionFactoryTest()
        {
            Parallel.For(0, 1, new ParallelOptions { MaxDegreeOfParallelism = 10 }, i =>
            {
                var userService = this.Container.CreateChildContainer().Resolve<UserService>();
                Trace.WriteLine(userService.Log.Logger.Name, "UserService.Log.Logger.Name");
                Trace.WriteLine(userService.Repository.Log.Logger.Name, "UserService.Repository.Log.Logger.Name");
            });
            var action = new Action(() =>
            {
                var log = this.Container.CreateChildContainer().Resolve<ILog>();
                Trace.WriteLine(log.Logger.Name, "Logger.Name");
            });
            action();
            var asyncResult = action.BeginInvoke(null, null);
            action.EndInvoke(asyncResult);
        }

        public class UserService
        {
            public UserRepository Repository { get; }
            public ILog Log { get; set; }

            public UserService(UserRepository repository, ILog log)
            {
                Repository = repository;
                Log = log;
            }
        }

        public class UserRepository
        {
            public ILog Log { get; }

            public UserRepository(ILog log)
            {
                Log = log;
            }
        }
    }
}

源代碼地址:https://github.com/echofool/Microsoft.Practices.Unity.Tracking

原諒我很懶,都不想解釋太多...

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved