为什么在Log4Net中命名了logger?

我一直在研究使用Castle Windsor将Log4Net ILog注入类的方法。 在大多数例子中,我看到Castle Windsor可以提供一个提供属性注入的“辅助器”,并注入ILogger(而不是ILog)。 我只找到了一个使用构造函数注入的示例,并且未使用辅助方法(请参阅Castle Windsordependency injection:使用调用方类型作为参数 )

在所有这些示例中,似乎Log4Net想要一个命名的记录器。 大多数示例引用Log4Net静态方法LogManager.GetLogger(此处为类名)。 这使得在不使用reflection或辅助方法的情况下定义CastleWindsor的依赖性是一个挑战(辅助方法可以与ctor注入一起使用)。 在查看Ilya Kogan的问题(上面的URL …)时,我想我不明白为什么需要,甚至想要一个命名的记录器。 我不能在任何地方使用同名的记录器吗?

例如,我不能只用硬编码的XXX名称注册记录器吗? (它似乎工作正常,最后,我只想记录 – 我不关心哪个记录器记录它…)是否存在范围问题? 是否存在内存泄漏问题? 为什么记录器不能/不应该是单件?

public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component.For().UsingFactoryMethod(() => log4net.LogManager.GetLogger("xxx")) ); } 

更新:

经过一些研究,可以使用硬编码的命名记录器 – 例如上面示例中的XXX,但是如果记录器的配置将记录器名称输出到日志文件,并且记录器名称是动态分配给与方法相同的名称,或者class,您自动获取对日志来源的引用。 日志文件中的上下文可能非常有用。

当专门针对ctor注射时,似乎有5种可能的选择……

  • 使用单例而不使用命名记录器(因此不会在日志文件中报告)
  • 使用ctor注射reflection(如Ilya Kogan的例子中所示)
  • 使用财产注入(通过协调人)
  • 使用后尖锐的AOP IL Injection进行记录
  • 使用CTOR注射(通过促进者)

使用Castle Windsor对DI Log4Net日志进行推荐的方法是使用Facilities。 已经为Log4Net创建了一个,并且在本教程中演示了它的用法。

好问题。

简而言之,log4net需要命名记录器,因为这些名称用于过滤日志输出(有关详细信息,请参阅log4net文档)。 类型名称只是一个方便的约定,因为它为您提供额外的上下文,并且正确使用命名空间允许您执行诸如“将所有NHibernate消息记录到单独的文件”之类的操作

这也是为什么通常,如果你没有使用容器,你的类中有一个静态记录器属性/字段。

您所指的ILogger是Castle中的日志记录抽象,其中一个可以用于log4net。

虽然LoggingFacility提供了对ILogger提供依赖性的开箱即用支持,但它决不会强迫您这样做。

你的ILog注册应该重写如下(我是从内存写的,所以细节可能会略有不同):

 Component.For() .UsingFactoryMethod((k, c) => log4net.LogManager.GetLogger(c.RequestedType)) .LifestyleTransient() 

c.RequestedType将为您提供满足依赖关系的类型,并使其成为瞬态将避免所有类型都将重用以请求依赖关系的第一个类型命名的log​​ger的单个实例的问题。