bar*_*ker 4 c# reflection log4net dependency-injection castle-windsor
我一直在研究使用Castle Windsor将Log4Net ILog注入类的方法.在大多数例子中,我看到Castle Windsor可以提供一个提供属性注入的"辅助器",并注入ILogger(而不是ILog).我只找到了一个使用构造函数注入的示例,并且未使用辅助方法(请参阅Castle Windsor依赖注入:使用调用方类型作为参数)
在所有这些示例中,似乎Log4Net想要一个命名的记录器.大多数示例引用Log4Net静态方法LogManager.GetLogger(此处为类名).这使得在不使用反射或辅助方法的情况下定义CastleWindsor的依赖性是一个挑战(可以将辅助方法与ctor注入一起使用).在查看Ilya Kogan的问题(上面的URL ...)时,我想我不明白为什么需要,甚至想要一个命名的记录器.我不能在任何地方使用同名的记录器吗?
例如,我不能只用硬编码的XXX名称注册记录器吗?(它似乎工作正常,最后,我只想记录 - 我不关心哪个记录器记录它...)是否存在范围问题?是否存在内存泄漏问题?为什么记录器不能/不应该是单件?
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<log4net.ILog>().UsingFactoryMethod(() => log4net.LogManager.GetLogger("xxx"))
);
}
Run Code Online (Sandbox Code Playgroud)
更新:
经过一些研究,可以使用硬编码的命名记录器 - 例如上面示例中的XXX,但是如果记录器的配置将记录器名称输出到日志文件,并且记录器名称是动态分配给与方法相同的名称,或者class,您可以自动获取对日志来源的引用.日志文件中的上下文可能非常有用.
当专门针对ctor注射时,似乎有5种可能的选择......
好问题.
简而言之,log4net需要命名记录器,因为这些名称用于过滤日志输出(有关详细信息,请参阅log4net文档).类型名称只是一个方便的约定,因为它为您提供了额外的上下文,并且正确使用命名空间允许您执行诸如"将所有NHibernate消息记录到单独的文件"之类的操作
这也是为什么通常,如果你没有使用容器,你的类中有一个静态的logger属性/字段.
在ILogger你指的是对日志记录在城堡的抽象,其中之一可以是log4net的.
尽管LoggingFacility提供开箱即用的提供依赖性的提供ILogger绝不会强迫您这样做.
你的ILog注册应该重写如下(我是从内存写的,所以细节可能会略有不同):
Component.For<log4net.ILog>()
.UsingFactoryMethod((k, c) => log4net.LogManager.GetLogger(c.RequestedType))
.LifestyleTransient()
Run Code Online (Sandbox Code Playgroud)
c.RequestedType 将为您提供满足依赖关系并使其成为瞬态的类型将避免所有类型都将重用以请求依赖关系的第一个类型命名的单个logger实例的问题.