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


場景:我們做項目的時候常常會引用第三方日志框架來幫助我們記錄日志,日志組件的用途主要是審計、跟蹤、和調試。就說我最常用的日志組件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

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

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com