如何在.NET 6中注入ILogger<Startup>

问题描述 投票:0回答:1

最近我们从.NET 2 迁移到.NET 6。我想继续使用startup.cs 文件。所以我重构了program.cs和startup.cs文件如下

程序.cs

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
    .CreateBootstrapLogger();
Log.Information("Starting up!");

try
{
    var builder = WebApplication.CreateBuilder(args);
    builder.Host.UseSerilog((context, services, configuration) => configuration
                .ReadFrom.Configuration(context.Configuration)
                .Enrich.FromLogContext());
        
    var startup = new Startup(builder.Configuration, builder.Environment);
    startup.ConfigureServices(builder.Services);
    var app = builder.Build();
    startup.Configure(app);
    app.Run();    
}
catch (Exception ex)
{
    Log.Fatal(ex, "An unhandled exception occurred during bootstrapping");
}
finally
{
    Log.CloseAndFlush();
}

Startup.cs

namespace Foo.Bar
{

    public class Startup
    {
        private IConfiguration Configuration { get; }
        private IWebHostEnvironment Environment { get; }

        public Startup(IConfiguration configuration, IWebHostEnvironment environment)
        {
            Configuration = configuration;
            Environment = environment;
        }
      
        public void ConfigureServices(IServiceCollection services)
        {
            
        }
        
        public void Configure(WebApplication app)
        {
            var logger = app.Logger;
            var appLifetime = app.Lifetime;            

            logger.LogInformation("Started Configure Method.");

            appLifetime.ApplicationStarted.Register(() =>
            {
                logger.LogInformation("Application started. {0}", DateTime.UtcNow);
            });
            
            appLifetime.ApplicationStopped.Register(() =>
            {
                logger.LogInformation("Application stopped. {0}", DateTime.UtcNow);
            });      


        }
    }
}

appsettings.json

Serilog": {
    "Using": [ "Serilog.Sinks.Console" ],
    "MinimumLevel": {
      "Default": "Error",
      "Override": {
        "Foo.Bar.Startup": "Information",
        "Microsoft": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "Console"
      }
    ]
  },

在应用程序设置中我配置了覆盖

"Foo.Bar.Startup": "Information"
。但是它不记录来自Configure()方法的信息日志。我认为这是因为在配置方法中记录器不是
ILogger<Startup>

但是如果我将覆盖部分更改为

"Foo.Bar": "Information"
那么它的日志信息来自 Startup.cs

我想弄清楚

ILogger<T>
是什么类型的 WebApplication.Logger (所以我可以在覆盖部分使用该类型) 或者如何在startup.cs中注入
ILogger<Startup>

.net-6.0 serilog asp.net-core-6.0
1个回答
0
投票

如果你去看类

WebApplication
的实现,你会看到构造函数

    internal WebApplication(IHost host)
    {
        _host = host;
        ApplicationBuilder = new ApplicationBuilder(host.Services, ServerFeatures);
        Logger = host.Services.GetRequiredService<ILoggerFactory>().CreateLogger(Environment.ApplicationName ?? nameof(WebApplication));

        Properties[GlobalEndpointRouteBuilderKey] = this;
    }

在这里我们可以看到

Logger
是基于
host.Services
的,所以在
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
之间的某个地方你需要调用

        builder.Logging.ClearProviders();
        builder.Services.AddSerilog(logger, true);

我更喜欢称之为

ClearProviders
以防万一删除默认情况下存在的任何可能的记录器,因此
Serilog
是唯一的记录器

© www.soinside.com 2019 - 2024. All rights reserved.