C# 如何使用Unity 2.0注入Log4Net ILog实现
最终,这与设置log4Net有关,但一般来说,问题不是特定于日志 一般来说,我想弄清楚的是,在Microsoft Unity 2.0中,如何实现与Castle.Facility.Logging.LoggingFacility相当的功能。也就是说,能够声明对记录器的依赖关系,并使用注入记录器的对象的类型初始化记录器 本着“测试胜过千言万语”的精神,我需要的是:C# 如何使用Unity 2.0注入Log4Net ILog实现,c#,dependency-injection,unity-container,log4net,castle-windsor,C#,Dependency Injection,Unity Container,Log4net,Castle Windsor,最终,这与设置log4Net有关,但一般来说,问题不是特定于日志 一般来说,我想弄清楚的是,在Microsoft Unity 2.0中,如何实现与Castle.Facility.Logging.LoggingFacility相当的功能。也就是说,能够声明对记录器的依赖关系,并使用注入记录器的对象的类型初始化记录器 本着“测试胜过千言万语”的精神,我需要的是: class Logger\u IOC\u测试 { //[测试] public void Logger\u应使用\u初始化\u使用\u it
class Logger\u IOC\u测试
{
//[测试]
public void Logger\u应使用\u初始化\u使用\u it()的\u对象的\u类型\u
{
var container=new UnityContainer();
/*配置魔法可能也包括注册
*自定义idependencySolverPolicy或BuilderStrategy
*去这里。。。
*/
RegisterType(新的ContainerControlledLifetimeManager());
var user=container.Resolve();
Assert.True(user.Logger.GetUserType()==user.GetType());
}
}
接口ILogger
{
类型GetUserType();
}
类记录器:ILogger
{
私有只读类型_类型;
公共记录器(类型)
{
_类型=类型;
}
公共类型GetUserType()
{
返回型;
}
}
类记录器用户
{
公共只读ILogger记录器;
公共记录器用户(ILogger记录器)
{
记录器=记录器;
}
}
在对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);
}
}
class Logger\u IOC\u测试
{
[测试]
public void Logger\u应使用\u初始化\u使用\u it()的\u对象的\u类型\u
{
var container=new UnityContainer();
container.AddNewExtension();
RegisterType(新的ContainerControlledLifetimeManager());
var user=container.Resolve();
Assert.True(user.Logger.GetUserType()==user.GetType());
}
}
类日志扩展:UnityContainerExtension
{
受保护的覆盖无效初始化()
{
SetDefault(typeof(IConstructorSelectorPolicy),new LoggingConstructorSelectorPolicy());
}
}
公共类日志构造函数SelectorPolicy:DefaultUnityConstructorSelectorPolicy
{
受保护的重写IDependencySolverPolicy CreateSolver(ParameterInfo参数)
{
return parameter.ParameterType==typeof(ILogger)
?新LoggerResolverPolicy(参数.Member.DeclaringType)
:base.CreateResolver(参数);
}
}
类LoggerResolverPolicy:IDependencyResolverPolicy
{
私有只读类型_依赖类型;
公共日志解析策略(类型相关类型)
{
_依亲类型=依亲类型;
}
公共对象解析(IBuilderContext上下文)
{
返回新的记录器(_类型);
}
}
我不知道这是否是你想要的,但几个月前我看到了,当我看到你的问题时,我想起了这一点。我没有使用Unity,所以我无法将您发布的内容与链接中的内容进行比较。希望它对您有用:
我一直在尝试实现相同的结果,即能够使用Unity的构造函数注入将正确配置的
ILog
实例插入到依赖项中
最后,我写了自己的“log4net”unity扩展来实现这一点(部分灵感来自另一位回答者Kenneth Baltrinic写的博客文章)
这允许您向Unity注册一次扩展:
var container = new UnityContainer();
container.AddNewExtension<Log4NetExtension>();
可在此处找到扩展名:
更多信息请点击此处:
编辑此功能现在以的形式提供。上述扩展功能运行良好,但MVC5用户需要更多配置信息。下面是使用unity的步骤 在名称空间上方的startup.cs类顶部添加以下行 [程序集:log4net.Config.XmlConfigurator(ConfigFile=“Web.Config”,Watch=true)] 在global.asax
应用程序启动
方法中添加以下信息:
log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
unity容器的其余配置应如下所示:
container.AddNewExtension<Log4NetExtension>();
container.AddNewExtension();
确保您的web.config中添加了一个
appender
。这应该是让它正常工作。祝你好运有了Unity 5及以上版本,你现在可以从中使用Unity自己的Log4Net扩展
您只需安装Nuget并将扩展添加到容器中:
container.AddNewExtension<Log4NetExtension>();
container.AddNewExtension();
它将自动与任何使用
ILog
作为依赖项的类一起工作。您可以使用以下代码注入Log4Net
log4net.Config.BasicConfigurator.Configure();
container.RegisterType<ILog>(new InjectionFactory(x => LogManager.GetLogger(typeof(Program))));
这一次你把锤子敲在头上了。这正是我想要的,比我的解决方案要好得多。非常感谢。为了它的价值,我从论坛和david的博客中收集了代码,并将它们放在我的博客上的一个地方。在Unity.codeplex讨论中有更高的抽象级别
LogCreation:UnityContainerExtension,其中U:ILogFactory,new()
。它将日志创建与日志框架分离。因此,可以对NLog使用相同的方法,例如,唯一的一件事是为特定的日志框架实现LogFactory。我已经结合了源代码,但我一辈子都无法阅读web.config log4net configurati
log4net.Config.BasicConfigurator.Configure();
container.RegisterType<ILog>(new InjectionFactory(x => LogManager.GetLogger(typeof(Program))));
public class MyClass
{
private readonly ILog logger;
public MyClass(ILog logger)
{
this.logger = logger;
}
}