如何在 ASP.NET MVC 6 中注册 ILogger 以进行注入

Posted

技术标签:

【中文标题】如何在 ASP.NET MVC 6 中注册 ILogger 以进行注入【英文标题】:How to register ILogger for injection in ASP.NET MVC 6 【发布时间】:2015-05-12 15:11:18 【问题描述】:

我有一个 ASP.NET MVC 6 (beta-4) 应用程序。

public void ConfigureServices(IServiceCollection services)

    // Logging
    services.AddLogging();

    // ...


public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)

    // Add the console logger.
    loggerfactory.AddConsole(minLevel: LogLevel.Warning);

    // ...

而且我有一个控制器...

public class HomeController : 
    Controller

    ILogger _logger;

    public HomeController(ILogger logger) 
    
        _logger = logger;
    

    // ...

但是当我没有以某种方式正确注册服务时:InvalidOperationException: Unable to resolve service for type 'Microsoft.Framework.Logging.ILogger' while attempting to activate 'HomeController'.。我在注册记录器时做错了什么?

【问题讨论】:

你没有注册ILogger 那不是service.AddLogging()吗?我可能对此做了一个宏伟的假设,是时候去源头潜水了。 所以,AddLogging() 应该注册ILogger<>。也许我需要注入ILogger<T> 而不是ILogger 刚刚自己查看了 vNext 源代码,我认为您是对的。但是,我仍然不想依赖框架定义的抽象。如需更多信息,请参阅this。 哦,我以为我把代码链接粘贴到了:github.com/aspnet/Logging/blob/…。 Microsoft 提供了一种抽象,因此您只需进行一些配置即可使用任何记录器。我可以接受,而不是坚持一个。虽然我从来没有费心去更换记录仪。 【参考方案1】:

我认为services.AddLogging(); 正在做正确的事情并注册ILogger。查看源代码(https://github.com/aspnet/Logging/blob/d874c5726e713d3eb34938f85faf7be61aae0f2a/src/Microsoft.Framework.Logging/LoggingServiceCollectionExtensions.cs)后,我发现它实际上是在注册ILogger<>。将ILogger 的签名更改为ILogger<HomeController> 使上面的示例工作。

public class HomeController : 
    Controller

    ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger) 
    
        _logger = logger;
    

    // ...

感谢@Steve 让我找到了正确的方法。

【讨论】:

这行得通。我读到他们将更改 RC2 以让 返回任何 T(如 ),这样您就可以真正获得您的实现,而不仅仅是接口方法。目前,您可以将任何东西放在那里并且它可以工作,看起来它会忽略它。我测试了 ILogger 只是为了测试该理论并且它有效。 T 的实际用途是日志上下文。 - 你调用 ILogger ,其中 T 通常是调用类型。但实际上可以。 您也可以指定 ILoggerFactory,如此处所述docs.asp.net/en/latest/fundamentals/logging.html 真正的问题是签名。这一直为我工作。 ILogger。非常感谢。 在我目瞪口呆了几个小时之后,这才救了我。【参考方案2】:

services.AddLogging(); 对我不起作用,所以我将这两个语句添加到ConfigureServices

services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));

现在 DI 容器很开心,一切正常。

【讨论】:

【参考方案3】:

只需将此行添加到ConfigureServices

services.AddSingleton(Serilog.Log.Logger);

【讨论】:

【参考方案4】:

.NET 5.0 解决方案;它也适用于普通控制器和通用控制器:

public class EnhancedGeneric<T> : BaseApiController

    private readonly ILogger _logger;

    public EnhancedGeneric(ILoggerFactory logger)
    
        _logger = logger.CreateLogger(typeof(T).Name);
    

    public void OnGet()
    
        _logger.LogInformation("GET pages called.");
    

【讨论】:

以上是关于如何在 ASP.NET MVC 6 中注册 ILogger 以进行注入的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ASP.NET 5 MVC 6 保护 Web API

如何在 ASP.NET 核心 MVC 中使用一次性密码 (OTP) 注册手机号码,而不是使用 2FA

如何在 Asp.Net 5 (MVC 6) 中使用实体框架 6.x

ASP.NET Core 3.1 MVC 如何让用户在注册时选择自己的角色?

如何在 ASP.Net MVC 6 中编辑和继续

如何在 ASP.NET 5 MVC 6 (vNext) 中定义 Identity 的密码规则?