5

我一直在研究使用 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"))
                );
        }

更新:

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

在专门解决 ctor 注入时,似乎有 5 种可能的选择......

  • 使用单例而不使用命名记录器(因此不在日志文件中报告)
  • 将反射与 ctor 注入一起使用(如 Ilya Kogan 的示例所示)
  • 使用属性注入(通过促进者)
  • 使用 post-sharp AOP IL 注入进行日志记录
  • 使用 CTOR 注入(通过促进者)
4

2 回答 2

6

好问题。

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

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

您指的ILogger是Castle over logging 中的抽象,其中之一可以用于log4net。

虽然LoggingFacility提供ILogger对它的依赖的开箱即用支持绝不是强迫您这样做。

你的ILog注册应该改写如下(我是凭记忆写的,所以细节可能会略有不同):

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

c.RequestedType将为您提供满足依赖项的类型并使其成为瞬态将避免所有类型将重用以请求依赖项的第一个类型命名的单个记录器实例的问题。

于 2012-11-14T22:41:20.160 回答
4

使用 Castle Windsor DI Log4Net 日志的推荐方法是使用设施。已经为 Log4Net 创建了一个,本教程演示了它的使用。

于 2012-11-14T22:31:34.877 回答