在ASP.NET Core 2中的Webhost之前开始记录

时间:2018-08-27 13:13:46

标签: c# asp.net-core serilog asp.net-core-2.1

我想在webhost之前开始记录,因此记录了启动错误。因此,我遵循了Serilog's recommended init order:1)配置,2)日志记录,3)Webhost。我没有使用CreateDefaultBuilder()

所以我的Program.cs有:

// setup config
var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configuration = new ConfigurationBuilder()
  .SetBasePath(Directory.GetCurrentDirectory())
  .AddJsonFile("appsettings.json", optional:false, reloadOnChange:true)
  .AddJsonFile($"appsettings.{envName}.json", optional:true, reloadOnChange:true)
  .AddEnvironmentVariables()
  .AddCommandLine(args)
  .Build();

// setup Serilog logging
Log.Logger = new LoggerConfiguration()
  .ReadFrom.Configuration(configuration)            // <<< uses config from above
  .CreateLogger()

// setup webhost
new WebHostBuilder()
  .UseConfiguration(configuration)                  // <<< uses config from above
  .UseKestrel()
  .UseContentRoot(Directory.GetCurrentDirectory())
  .UseStartup<Startup>()
  .UseSerilog()
  .Build()
  .Run();

这有效,但是即使我指定了appsettings.json,也未检测到reloadOnChange:true中的更改。

但是,当我使用ConfigureAppConfiguration()时,会检测到更改:

new WebHostBuilder()
  .ConfigureAppConfiguration((context, config) => {
    // .. duplicate config here
  })
  .UseKestrel()
  .UseContentRoot(Directory.GetCurrentDirectory())
  .UseStartup<Startup>()
  .UseSerilog()
  .Build()
  .Run();

但这意味着重复,并且可能存在无法预料的问题-即这是黑客。我该如何解决?

更新

根据@StephenZeng的回答,UseConfiguration在这里无济于事,所以我想我需要使用ConfigureAppConfiguration。但是问题仍然存在-如何先初始化配置,然后多次使用它而不重新定义它?

3 个答案:

答案 0 :(得分:2)

该文档是设计使然的:

“ UseConfiguration仅将密钥从提供的IConfiguration复制到主机构建器配置。因此,对于JSON,INI和XML设置文件,设置reloadOnChange:true无效。”

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-2.1&tabs=aspnetcore2x

答案 1 :(得分:2)

我遇到了同样的问题,我创建了一个方法来配置构建器。然后,我从Main和构建Web主机时都调用该方法。像这样:

public static class Program
{
  public static int Main()
  {
    var configuration = new ConfigurationBuilder()
      .AddConfiguration()
      .Build();

    // setup Serilog logging
    Log.Logger = new LoggerConfiguration()
      .ReadFrom.Configuration(configuration)
      .CreateLogger();

    // Code removed for brevity...
  }

  private static IWebHost BuildWebHost() =>
    WebHost.CreateDefaultBuilder()
      .UseSerilog()
      .UseStartup<Startup>()
      .ConfigureAppConfiguration((hostingContext, config) =>
      {
        // Clear default configuration
        config.Sources.Clear();

        // Replace with our own configuration
        config.AddConfiguration();
      })
      .Build();

  private static IConfigurationBuilder AddConfiguration(this IConfigurationBuilder self) =>
    self
      .SetBasePath(Directory.GetCurrentDirectory())
      .AddJsonFile("appsettings.json", optional:false, reloadOnChange:true)
      .AddJsonFile($"appsettings.{envName}.json", optional:true, reloadOnChange:true)
      .AddEnvironmentVariables();
}

答案 2 :(得分:0)

解决方案是避免使用UseConfiguration,而改用ConfigureAppConfiguration

// setup config
// ..as before
// ..this is done only once

// setup Serilog logging
// ...as before

// setup webhost
new WebHostBuilder()
  .ConfigureAppConfiguration((context, config) => {
    config.AddConfiguration(configuration);  // <<< uses config from above
  })
  .UseKestrel()
  .UseContentRoot(Directory.GetCurrentDirectory())
  .UseStartup<Startup>()
  .UseSerilog()
  .Build()
  .Run();