I want to start logging before webhost, so startup errors are logged. So I followed Serilog's recommended init order: 1) configuration, 2) logging, 3) webhost. I'm not using CreateDefaultBuilder()
.
So my Program.cs
has:
// 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();
This works, but changes in appsettings.json
are not detected even though I specified reloadOnChange:true
.
However when I use ConfigureAppConfiguration()
then changes are detected:
new WebHostBuilder()
.ConfigureAppConfiguration((context, config) => {
// .. duplicate config here
})
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();
But that means duplication and possibly unforseen problems - i.e. this is a hack. How do I solve this?
UPDATE
As per @StephenZeng's answer, UseConfiguration
won't help me here, so I suppose I need to use ConfigureAppConfiguration
. But the problem remains - how do I init my config first, then use it multiple times without redefining it?
The solution is to avoid UseConfiguration
and use ConfigureAppConfiguration
instead:
// 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();