C# 依赖项注入ILogger工厂,中间件中的ILogger,记录器未执行

C# 依赖项注入ILogger工厂,中间件中的ILogger,记录器未执行,c#,asp.net-core,dependency-injection,middleware,ilogger,C#,Asp.net Core,Dependency Injection,Middleware,Ilogger,试图构建一个中间件来记录每个请求的信息。 ASP.NET核心3.1 学习一些基础知识 我想了解一些奇怪的行为。这是我的中间件构造函数: public ContextRequestLoggingMiddleware( RequestDelegate next, ILoggerFactory loggerFactory ) { this._next = next; _logger = loggerFactory.CreateLogger( "ContextRequestLo

试图构建一个中间件来记录每个请求的信息。 ASP.NET核心3.1 学习一些基础知识

我想了解一些奇怪的行为。这是我的中间件构造函数:

public ContextRequestLoggingMiddleware( RequestDelegate next, ILoggerFactory loggerFactory ) {
    this._next = next;
    _logger = loggerFactory.CreateLogger( "ContextRequestLoggingMiddleware" );            
}
使用此选项可以如期工作。每个请求都会记录一条消息:

public async Task InvokeAsync (HttpContext context ) {
    _logger.LogInformation( "test from middleware" );
    await _next( context );    
}
当我使用下面的代码时:

_logger = loggerFactory.CreateLogger<ContextRequestLoggingMiddleware>();
我无法插入纯
ILogger
,因为它会引发运行时错误:

尝试激活“Microsoft.AspNetCore.Builder.ContextRequestLoggingMiddleware”时,无法解析类型“Microsoft.Extensions.Logging.ILogger”的服务

再次检查对象,我并没有看到我使用的不同方法之间的差异<为什么?这是为什么?<强>我会考虑<代码> ILogger <代码>作为最佳选择,但是为什么它在这里不起作用?在控制器中它确实对我有用。谢谢你的解释

对于上下文,my
CreateHostBuilder

public static IHostBuilder CreateHostBuilder( string[] args ) =>
    Host.CreateDefaultBuilder( args )
        .ConfigureLogging( ( hostContext, loggingBuilder ) => {
            loggingBuilder.ClearProviders();
            loggingBuilder.AddConfiguration( hostContext.Configuration.GetSection( "Logging" ) );
            loggingBuilder.AddCustomFileLogger();
        }
        ).ConfigureWebHostDefaults( webBuilder => {
            webBuilder.UseStartup<Startup>();
        } );
编辑 决议: 我犯了一个错误,在构建类
ContextRequestLoggingMiddleware
时,我将其放在了名称空间
Microsoft.AspNetCore.Builder
下。有了它,让记录器在中间件中工作的唯一方法就是通过iLogger工厂并创建记录器,但它只有一种方式工作

_logger = loggerFactory.CreateLogger( "ContextRequestLoggingMiddleware" )
一旦我将类放在不同的名称空间下,其他方法也开始起作用

_logger = loggerFactory.CreateLogger<ContextRequestLoggingMiddleware>()
\u logger=loggerFactory.CreateLogger()
而且传递
ILogger
现在也可以了

所以下面的构建类现在对我来说很有用。 有趣的是名称空间的改变如何使它工作

namespace NPARetrieval.Middleware {
public class ContextRequestLoggingMiddleware {
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public ContextRequestLoggingMiddleware( RequestDelegate next, ILogger<ContextRequestLoggingMiddleware> logger ) {
        this._next = next;
        _logger = logger;
    }


    public async Task InvokeAsync (HttpContext context ) {
        _logger.LogInformation( "test from middleware" );
        await _next( context );    
    }
}
namespace.retrieval.Middleware{
公共类ContextRequestLogging中间件{
private readonly RequestDelegate\u next;
专用只读ILogger\u记录器;
公共ContextRequestLoggingMiddleware(RequestDelegate下一步,ILogger记录器){
这个。_next=next;
_记录器=记录器;
}
公共异步任务InvokeAsync(HttpContext上下文){
_logger.LogInformation(“来自中间件的测试”);
等待下一步(上下文);
}
}

}

如果显式地注入
ILogger
,会发生什么?为什么要从工厂开始?@Nkosi如文所述,它编译并运行,但没有执行代码行_logger.LogInformation,它只是越过它。我从中间件记录东西的唯一方法是使用factory。这就是问题的原因,试图理解为什么只有一种方法有效,而其他方法无效。问题几乎肯定是您对
loggingBuilder.ClearProviders()
的调用。
_logger = loggerFactory.CreateLogger<ContextRequestLoggingMiddleware>()
namespace NPARetrieval.Middleware {
public class ContextRequestLoggingMiddleware {
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public ContextRequestLoggingMiddleware( RequestDelegate next, ILogger<ContextRequestLoggingMiddleware> logger ) {
        this._next = next;
        _logger = logger;
    }


    public async Task InvokeAsync (HttpContext context ) {
        _logger.LogInformation( "test from middleware" );
        await _next( context );    
    }
}