解决错误 - 无法解析“Serilog.ILogger”类型的服务

Posted

技术标签:

【中文标题】解决错误 - 无法解析“Serilog.ILogger”类型的服务【英文标题】:Solving error - Unable to resolve service for type 'Serilog.ILogger' 【发布时间】:2016-11-20 06:11:13 【问题描述】:

我正在尝试在 ASP.NET 核心应用程序(.NET 框架)中实现 SeriLog

以下是我到目前为止执行的步骤-

1) 在 Project.json 中添加以下引用

"Serilog": "2.2.0",
"Serilog.Extensions.Logging": "1.2.0",
"Serilog.Sinks.RollingFile": "2.0.0",
"Serilog.Sinks.File": "3.0.0"

2) 在 Startup 类的构造函数中添加了以下几行-

Log.Logger = new LoggerConfiguration()
           .MinimumLevel.Debug()
           .WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "log-Date.txt"))
           .CreateLogger();

3) 在 Startup 类的 configure 方法中添加以下行-

loggerFactory.AddSerilog();

4) 像这样将记录器注入 HomeController-

ILogger logger;

    public HomeController(ILogger logger)
    
        this.logger = logger;
    

5) 在关于操作中,尝试像这样记录异常-

public IActionResult About()
    
        ViewData["Message"] = "Your application description page.";

        try
        
            throw new Exception("Serilog Testing");
        
        catch (System.Exception ex)
        
            this.logger.Error(ex.Message);
        

        return View();
    

在运行我的应用程序时,我遇到了错误-

System.InvalidOperationException:无法解析服务类型 尝试激活时出现“Serilog.ILogger” 'AspNetCore_SeriLog_trial1.Controllers.HomeController'。在 Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired) 在 lambda_method(Closure, IServiceProvider, Object[]) 在 Microsoft.AspNetCore.Mvc.Internal.TypeActivatorCache.CreateInstance[TInstance](IServiceProvider serviceProvider,类型 implementationType) 在 Microsoft.AspNetCore.Mvc.Controllers.DefaultControllerActivator.Create(ControllerContext 控制器上下文)在 Microsoft.AspNetCore.Mvc.Controllers.DefaultControllerFactory.CreateController(ControllerContext 上下文)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__26.MoveNext()

有人可以帮我解决这个问题吗? Serilog 是否缺少任何配置?

【问题讨论】:

How to register ILogger for injection in ASP.NET MVC 6的可能重复 【参考方案1】:

尝试在您的控制器中执行以下操作。

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

【讨论】:

我试过这个但得到错误 - Error CS0308 The non-generic type 'ILogger' cannot be used with type arguments 您是否在使用 seri ilogger 接口,然后尝试将其替换为日志库中存在的 Microsoft ilogger 接口。【参考方案2】:

如果你需要使用ILogger(来自Serilog)而不是ILogger&lt;HomeController&gt;(来自Microsoft.Extensions.Logging),你可以在你的Startup类上注册ILogger

services.AddSingleton(Log.Logger);

【讨论】:

我用过这个。 Tnx! 完美运行!太棒了!【参考方案3】:

您的控制器中有以下两行中的哪一行?

using Serilog;
using Microsoft.Extensions.Logging;

如果是前者 (using Serilog;),那可能是你的问题。

当您注册服务时,您实质上是在说“当构造函数请求 Microsoft.Extensions.Logging.ILogger 时,向它们传递一个 Serilog 实例,因为我正在使用 Serilog 进行日志记录”,但随后在您的构造函数中您不是在要求 Microsoft.Extensions.Logging.ILogger,而是在要求 Serilog.ILogger,而您的应用程序变得混乱,因为您还没有定义要为Serilog.ILoger 注入的服务,您已经为Microsoft.Extensions.Logging.ILogger 定义了一项服务

请记住,您正在实现 Microsoft 的 ILogger 接口:您的构造函数不需要知道您正在使用 Serilog...事实上,您不希望它知道!重点是您可以随时将 Serilog 换成不同的记录器,而无需更改代码。

在您的构造函数中将using Serilog; 更改为using Microsoft.Extensions.Logging;,您将请求正确的服务类型

【讨论】:

【参考方案4】:

你错过了在控制器构造函数中注入你的接口:

ILogger<HomeController> logger = null;

public HomeController(ILogger<HomeController> _logger)

    logger = _logger;

您还必须在 Program.cs 中添加 UseSerilog:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseSerilog();

【讨论】:

【参考方案5】:

我知道这是一个老问题,但我刚刚遇到了这个问题并找到了不同的解决方案。

我将Microsoft.Extensions.Logging 换成Serilog,但我错过了将其从构造函数参数列表中删除。

public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger logger)

一旦我删除了那个参数,错误就消失了。

public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment)

看起来 OP 试图通过构造函数注入记录器,但应该为该控制器创建一个特定的记录器。你也可以static所以there's only 1 creation of the logger for every time this project runs, instead of 1 for every instance of the class.

public class HomeController : Controller

    private static readonly ILogger Logger = Log.ForContext<HomeController>();
    ...

    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment)
    
    ...
    

    ...

显然,发生的事情是编译器默认尝试为构造函数提供Microsoft.Extensions.Logging 记录器,而不是尝试匹配构造函数实际期望的Serilog 记录器,所以这就是错误的来源。

【讨论】:

【参考方案6】:

我遇到了这个问题“在尝试激活 'Controller_Name' 时无法解析类型 'interface_name' 的服务 ....

通过在 startup.cs 中添加以下行,我已经解决了同样的问题:

services.AddScoped<interface_name, Controller_Name>();

【讨论】:

以上是关于解决错误 - 无法解析“Serilog.ILogger”类型的服务的主要内容,如果未能解决你的问题,请参考以下文章

如何解决此问题 错误:无法解析包?

解决错误 - 无法解析“Serilog.ILogger”类型的服务

未找到模块:错误无法解析“child_process”,如何解决?

Jersey 客户端错误 - 无法解析无效的 Content-Type 标头(需要解决方法)

无法解析符号“注释”[重复]

导入节点模块时出现流错误“无法解析模块”