如何使用Unity 2.0注入Log4Net ILog实现

最终这与设置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(new ContainerControlledLifetimeManager()); var user = container.Resolve(); 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(); 

然后传入正确的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/

编辑现在可以作为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(); container.RegisterType(new ContainerControlledLifetimeManager()); var user = container.Resolve(); 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类的顶部。

[assembly:log4net.Config.XmlConfigurator(ConfigFile =“Web.config”,Watch = true)]

在global.asax application_startup方法中添加以下信息:

 log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config"))); 

Unity容器的其余配置应该是这样的:

 container.AddNewExtension(); 

确保在web.config中添加了一个appender 。 这应该是为了让它正常工作。 祝好运

使用Unity 5及更高版本,您现在可以使用Unity自己的Log4Net扩展来自https://github.com/unitycontainer/log4net 。

您所要做的就是安装Nuget并将扩展添加到容器中:

 container.AddNewExtension(); 

它将自动与任何使用ILog作为依赖项的类一起工作。