使用Microsoft.Extensions.Logging从静态成员进行日志记录

时间:2017-09-29 06:34:34

标签: logging asp.net-core

根据https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging,使用Microsoft.Extensions.Logging的建议方法似乎是通过依赖注入ILogger个对象。

在依赖注入不起作用(或不能正常工作)的情况下建议的模式是什么,例如在扩展方法,类型初始值设定项,静态属性和传递{的其他静态成员中{1}}会非常麻烦吗?

使用log4net(我的团队之前使用过),一个常见的模式是:

ILogger

是否有与public static class SomeExtensions { private static readonly ILog s_log = LogManager.GetLogger(typeof(SomeExtensions)); public static void ExtensionMethod (this SomeType someType) { s_log.Info("..."); } } 相似的既定或推荐模式?

4 个答案:

答案 0 :(得分:1)

DI对静态不太好用。从某种意义上说,它们是一种对立的设计哲学。 ASP.NET大量使用静态(HttpContext,任何人?),并且在很多方面使用依赖注入非常很困难。 ASP.NET Core选择避开静态并使用100%DI模型。

简而言之,如果你想使用依赖注入,你的静态使用应该消失。在大多数情况下,这实际上是一件非常好的事情。虽然它们可以用于某些事情,但滥用并且在大多数情况下非常有用。你可以用一个静态来做很多事情,你不能用单例范围内的依赖注入类来做,后者为你提供了更大的抽象和可重用性。

无法真正替换的静态的一种用法是扩展。当然,有一整套思想认为你不应该使用扩展,无论如何。但是,如果您需要或想要扩展,那么您要么无法从那些日志中进行登录,要么必须将logger实例作为参数传递。在许多情况下,必须通过记录器会严重限制扩展的有用性,因此您可能根本不会登录。然而,即使你认为扩展是好的和花花公子的学校,大多数人都同意它们也应该在范围上受限:即他们应该做一些简单的事情,不需要很多代码。如果是这种情况,实际登录的需求会急剧减少。

简而言之,它简单归结为您必须做出的设计决策。如果你想要依赖注射路线,静力学将是你家的瘟疫,你应该避免它们。

答案 1 :(得分:1)

TLDR :不,从不对任何建议提出异议,并且大多数情况下,它表示从不使用.NET Core中的静态实例或使用最少的静态实例。

===编辑===

推荐的方法是不要使用静态或直接实例化,而应该使用正确的DI或生命周期指令。 DOC here

长版

对于静态类,我讨论了如何在不依赖于DI的情况下设置Logger,以及静态类的DI有多糟糕。

从讨论中可以看出,NET核心应用程序中不希望使用静态方法,因此必须在生命周期中对其进行仔细管理。

由于Logger扩展程序是NET Core中使用DI的典型中间件,因此(据我所知)没有推荐的方法可以在静态类中进行构建,因为“按设计”并非必须如此。

因此,您最好自己动手或重复使用另一个记录器。

在可能的情况下,这是构建没有DI(但仍不是静态)的Logger的方法:

private readonly ILoggerFactory _logfactory;
private readonly ILogger _logger;

==== IN CONSTRUCTOR
_logfactory = (ILoggerFactory) new LoggerFactory();
_logger = new Logger<YourClass>(_logfactory);

显然,您可以通过不存放ILoggerFactory的方式来简化它。

希望它回答您的问题。

=====编辑======

我在生命周期文档中发现了执行我先前所说的语句的句子:link here

所说的句子是:

  

最佳做法是:

     
      
  • 设计服务以使用依赖项注入来获取其依赖项。
  •   
  • 避免使用有状态的静态类和成员。将应用设计为改为使用单例服务,这样可以避免创建全局状态。
  •   
  • 避免在服务中直接实例化依赖类。直接实例化将代码耦合到特定的实现。
  •   
  • 使应用程序类较小,构造合理且易于测试。
  •   

因此,我认为,由于它是Microsoft的正式文档,因此它提出了关于该主题的最后一点。

答案 2 :(得分:0)

感谢@ chris-pratt和@shad,pointing out的ASP.NET Core记录器方法与静态方法不能很好地兼容,而实际上finding according documentation则很好。

但是,在某些情况下,避免静电是困难的(或在主观上)是不希望的。因此,我的问题是要问在这种情况下是否有使用Microsoft.Extensions.Logging的既定模式。

该问题的唯一真实答案是@ alexandre-pires在a comment中给我指出了this Stackify article。其中,它展示了如何设置可在静态上下文中使用的集中式ILoggerFactory。但是,结论是仅继续使用NLog或Serilog并将Microsoft.Extensions.Logging转发到该库。

答案 3 :(得分:-1)

你可以像这样使用 Serilog:

using Serilog;

private static readonly ILogger log = Log.ForContext(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);