如何使用Unity 2.0注入Log4Net ILog实现
本文关键字:Log4Net ILog 实现 注入 何使用 Unity | 更新日期: 2023-09-27 18:03:56
最终,这与设置log4Net有关,但一般来说,问题不是特定于日志记录的。
一般来说,我想弄清楚的是,在Microsoft Unity 2.0中,如何做一些与Castle.Facilities.Logging.LoggingFacility等效的事情。也就是说,能够声明对记录器的依赖关系,并用要注入的对象的类型初始化记录器。
本着测试胜过千言万语的精神,以下是我需要的:
class Logger_IOC_Tests
{
//[Test]
public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
{
var container = new UnityContainer();
/* Configuration Magic probably involiving registering either
* a custom IDependencyResolverPolicy or BuilderStrategy
* goes here...
*/
container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());
var user = container.Resolve<LoggerUser>();
Assert.True(user.Logger.GetUserType() == user.GetType());
}
}
interface ILogger
{
Type GetUserType();
}
class Logger : ILogger
{
private readonly Type _type;
public Logger(Type type)
{
_type = type;
}
public Type GetUserType()
{
return _type;
}
}
class LoggerUser
{
public readonly ILogger Logger;
public LoggerUser(ILogger logger)
{
Logger = logger;
}
}
我不知道这是否是你想要的,但我几个月前看到了它,当我看到你的问题时,我想起了它。我没有使用Unity,所以我真的无法将你发布的内容与链接上的内容进行比较。希望它对你有用:
http://davidkeaveny.blogspot.com/2011/03/unity-and-log4net.html
我一直在尝试实现相同的结果,即能够使用Unity的构造函数注入将正确配置的ILog
实例插入到依赖项中。
最后,我写了自己的"log4net"统一扩展来做到这一点(部分灵感来自另一位回答者Kenneth Baltrinic写的一篇博客文章(。
这允许您向Unity:注册一次扩展
var container = new UnityContainer();
container.AddNewExtension<Log4NetExtension>();
然后传入正确的ILog记录器实例:
public class MyClass
{
private readonly ILog logger;
public MyClass(ILog logger)
{
this.logger = logger;
}
}
扩展可以在这里找到:
https://github.com/roblevine/UnityLoggingExtensions
更多信息请点击此处:http://blog.roblevine.co.uk/net/using-log4net-with-unity/
EDIT现在可以作为NuGet包使用
在对Unity源代码进行了数小时的挖掘之后,我提出了以下解决方案。但是,我更愿意找到一种方法,根据要解析的类型设置适当的依赖关系解析程序,而不是重写默认的构造函数选择器策略。首先,因为我之前为了其他目的重写了默认的构造函数选择器。另一方面,这个解决方案只处理通过构造函数注入的依赖项。对于完全覆盖,我认为也必须覆盖默认的属性和方法选择器。就我自己而言,我只需要构造函数。
class Logger_IOC_Tests
{
[Test]
public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
{
var container = new UnityContainer();
container.AddNewExtension<LoggingExtension>();
container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());
var user = container.Resolve<LoggerUser>();
Assert.True(user.Logger.GetUserType() == user.GetType());
}
}
class LoggingExtension : UnityContainerExtension
{
protected override void Initialize()
{
Context.Policies.SetDefault(typeof(IConstructorSelectorPolicy), new LoggingConstructorSelectorPolicy());
}
}
public class LoggingConstructorSelectorPolicy : DefaultUnityConstructorSelectorPolicy
{
protected override IDependencyResolverPolicy CreateResolver(ParameterInfo parameter)
{
return parameter.ParameterType == typeof(ILogger)
? new LoggerResolverPolicy(parameter.Member.DeclaringType)
: base.CreateResolver(parameter);
}
}
class LoggerResolverPolicy : IDependencyResolverPolicy
{
private readonly Type _dependantType;
public LoggerResolverPolicy(Type dependantType)
{
_dependantType = dependantType;
}
public object Resolve(IBuilderContext context)
{
return new Logger(_dependantType);
}
}
上述扩展运行良好,但MVC5用户需要更多配置信息。以下是使用统一的步骤。
将以下行添加到命名空间上方startup.cs类的顶部。
[程序集:log4net.Config.XmlConfigurator(ConfigFile="Web.Config",Watch=true(]
在global.asax application_startup
方法中添加以下信息:
log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
统一容器的其余配置应如下所示:
container.AddNewExtension<Log4NetExtension>();
请确保在web.config中添加了一个appender
。这样就可以正常工作了。好运
使用Unity 5及以上版本,您现在可以使用Unity自己的Log4Net扩展https://github.com/unitycontainer/log4net.
你所要做的就是安装Nuget并将扩展添加到你的容器中:
container.AddNewExtension<Log4NetExtension>();
它将自动处理任何使用ILog
作为依赖项的类。
您可以使用以下代码注入Log4Net
log4net.Config.BasicConfigurator.Configure();
container.RegisterType<ILog>(new InjectionFactory(x => LogManager.GetLogger(typeof(Program))));
typeof(程序(是使用的,因为我正在程序类中注册。使用可以使用类名或这个关键字
然后可以将ILog注入类
public class MyClass
{
private readonly ILog logger;
public MyClass(ILog logger)
{
this.logger = logger;
}
}