C# 依赖项注入ILogger工厂,中间件中的ILogger,记录器未执行
试图构建一个中间件来记录每个请求的信息。 ASP.NET核心3.1 学习一些基础知识 我想了解一些奇怪的行为。这是我的中间件构造函数: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
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 <代码>作为最佳选择,但是为什么它在这里不起作用?在控制器中它确实对我有用。谢谢你的解释
对于上下文,myCreateHostBuilder
:
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 );
}
}