【问题标题】:netcore: manually create a Logger without using LoggerFactorynetcore:不使用 LoggerFactory 手动创建 Logger
【发布时间】:2019-06-19 18:18:14
【问题描述】:

我正在使用以下方法创建控制台记录器:

_log = new LoggerFactory().AddConsole().CreateLogger(this.GetType().Name);

现在我收到以下警告:

controllers\DummyController.cs(31,20): warning CS0618:
'ConsoleLoggerExtensions.AddConsole(ILoggerFactory)' is obsolete: 
'This method is obsolete and will be removed in a future version. The 
recommended alternative is AddConsole(this ILoggingBuilder builder).' 

我不在依赖注入容器的上下文中。

更新: 我也尝试过像这样使用 DI:

var serviceProvider = new ServiceCollection()
    .AddLogging()
    .BuildServiceProvider();
var log = serviceProvider.GetService<ILogger>();
log.LogInformation("testing _log");

但我收到以下错误:

Error Message:                                                                                                                                                
  System.ArgumentNullException : Value cannot be null.                                                                                                         
Parameter name: logger                                                                                                                                        
Stack Trace:                                                                                                                                                  
   at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, String message, Object[] args)                                                                                                                                                             
   at Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(ILogger logger, String message, Object[] args)      

似乎我无法从容器中获取记录器

【问题讨论】:

  • 您可以通过反射或其他方式来实现。这可能有点矫枉过正,但在某些性能不是主要问题的情况下,我所做的只是创建我的 ServiceCollectionServiceProvider 并使用提供的扩展方法。
  • 谢谢,我也尝试过使用 DI,但似乎缺少一些东西。我更新了我的问题

标签: logging dependency-injection .net-core


【解决方案1】:

接口已更改,因此您可以在 LoggerFactory 上使用静态 Create() 工厂方法,并在配置提供程序的配置对象中传递一个委托。然后可以像以前一样使用工厂创建记录器:

    ILogger<Program> logger = LoggerFactory
        .Create(logging => logging.AddConsole())
        .CreateLogger<Program>();
    logger.LogInformation("Hello World!");

虽然应用程序通常应该使用主机构建器,但这在单元测试中非常有用,因为您可以传入一个写入控制台(而不是模拟)的真实记录器,并在测试结果中查看输出.

这取自简单的演练示例:https://github.com/sgryphon/essential-logging/tree/master/examples/GettingStarted

还有更多示例展示了如何通过主机构建器进行配置,以及如何使用 Microsoft 高性能日志记录模式。

【讨论】:

    【解决方案2】:

    如果您正在创建一个 DI 容器,您可以使用以下代码从工厂实例化一个记录器实例。

    var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.Create("mylogger");
    logger.LogInformation("Hello {0}", "world");
    

    或者,您可以从类型化界面创建它

    var logger = serviceProvider.GetRequiredService<ILogger<MyType>>();
    logger.LogInformation("Hello {0}", "world");
    

    无法执行以下操作:

    var logger = serviceProvider.GetRequiredService<ILogger>();
    

    由于非泛型接口未在依赖注入容器中注册,其原因是日志库从泛型类型推断记录器名称,并且当您仅使用ILogger 时,没有什么可以派生名称来自,而不是MyProject.MyNamespace.MyType

    有点跑题了,但是使用扩展方法GetRequiredService&lt;T&gt; 而不是GetService&lt;T&gt; 至少可以帮助您避免空引用异常。

    【讨论】:

      猜你喜欢
      • 2019-02-04
      • 1970-01-01
      • 2019-04-23
      • 2023-03-12
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      相关资源
      最近更新 更多