根据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("...");
}
}
相似的既定或推荐模式?
答案 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);