场景:我们做项目的时候常常会引用第三方日志框架来帮助我们记录日志,日志组件的用途主要是审计、跟踪、和调试。就说我最常用的日志组件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(, , new ParallelOptions { MaxDegreeOfParallelism = }, 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

原谅我很懒,都不想解释太多...

Microsoft.Practices.Unity 给不同的对象注入不同的Logger的更多相关文章

  1. 第九回 Microsoft.Practices.Unity.Interception实现基于数据集的缓存(针对六,七,八讲的具体概念和配置的解说)

    返回目录 概念 Microsoft.Practices.Unity.Interception是一个拦截器,它隶属于Microsoft.Practices.Unity组成之中,主要完成AOP的功能,而实 ...

  2. WPF Microsoft.Practices.Unity 注入大法简单示例

    最近新入职了公司,做WPF方向的项目,进来后看到这边大量运用了依赖注入来解耦,采用的是Microsoft.Practices.Unity. WPF的话,目前主要有两个技术来实现IOC,unity和ME ...

  3. 使用Microsoft.Practices.Unity 依赖注入

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

  4. 使用Microsoft.Practices.Unity 依赖注入 转载https://www.cnblogs.com/slardar1978/p/4205394.html

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

  5. 利用Microsoft.Practices.Unity的拦截技术,实现.NET中的AOP

    1.记住这个单词的意思:Interception(拦截) 2.首先说一下原理和背景 原理:所谓的AOP就是面向切面编程,这里不多说,百度搜索. 目的:个人认为是为了解耦,部分代码跟业务代码分离,业务代 ...

  6. Microsoft.Practices.Unity

    // // Summary: // Register a type mapping with the container. // // Parameters: // container: // Con ...

  7. VS - Microsoft.Practices.Unity

    PM>  Install-Package Unity Web.config <configSections> <section name="unity" t ...

  8. 20190703_创建 unity 的配置节处理程序时出错: The type name or alias Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension

    创建 unity 的配置节处理程序时出错: The type name or alias Microsoft.Practices.Unity.InterceptionExtension.Configu ...

  9. Microsoft.Practices.Unity入门

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

随机推荐

  1. SpringBoot笔记一

    1 开始 1.1 spring介绍 Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需"just run". 我们为Spring平台及第三方库 ...

  2. Android中使用shape制作一个旋转的progressbar

    public class ZNtestResActivity extends Activity { @Override public void onCreate(Bundle savedInstanc ...

  3. Android录音服务

    MediaRecorder Mediarecorder=new MediaRecorder();//创建一个MediaRecorder对象 Mediarecorder.setAudioSource(M ...

  4. HDU4452 Running Rabbits

    涉及知识点: 1. direction数组. 2. 一一映射(哈希). Running Rabbits Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  5. libsvm java 调用说明

    libsvm是著名的SVM开源组件,目前有JAVA.C/C++,.NET 等多个版本,本人使用的是2.9libsvm命名空间下主要使用类:svm_model 为模型类,通过训练或加载训练好的模型文件获 ...

  6. Android NOtification 使用(震动 闪屏 铃声)

    一. Notification 简介 在 android 系统中,在应用程序可能会遇到几种情况需要通知用户,有的需要用户回应,有的则不需要,例如: * 当保存文件等事件完成,应该会出现一个小的消息,以 ...

  7. DC综合流程

    Design Compiler and the Design Flow 步骤 将HDL描述的设计输入到Design Compiler中 Design Compiler使用technology libr ...

  8. CentOS6.7 下安装git

    在CentOS5的时代,由于yum源中没有git,所以需要预先安装一系列的依赖包.但在CentOS6的yum源中已经有git的版本了,可以直接使用yum源进行安装. $ sudo yum instal ...

  9. 作业三 ATM

    模拟实现一个ATM+购物商场程序 1.额度15000自定义 商城和银行两个帐户 2.实现购物商城,买东西加入购物车,调用信用卡接口结账 3.可以提现,手续费5%,提现额度不能超过50% 4.每月22日 ...

  10. Function.prototype.bind

    解析Function.prototype.bind 简介 对于一个给定的函数,创造一个绑定对象的新函数,这个函数和之前的函数功能一样,this值是它的第一个参数,其它参数,作为新的函数的给定参数. b ...