How to read configuration settings before initializing a Host in ASP .NET Core?
The answer by UncleDave is certainly the best and most correct way to do this, but if you want to use the default configuration without recreating the logic yourself, it is not easy to get access to the IConfiguration
and the IWebHostBuilder
in the same place.
In order to do this, you can take advantage of the fact that the concrete Configuration is built before other services such as the web host are built. You can use ConfigureAppConfiguration()
to access the config then use it to continue building the IWebHostBuilder
.
For example:
public static async Task Main(string[] args)
{
var hostBuilder = Host.CreateDefaultBuilder(args);
var builder = hostBuilder
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
// make sure to put this at the end of this method
webBuilder.ConfigureAppConfiguration(configBuilder =>
{
// compile a temporary configuration instance
var configuration = configBuilder.Build();
// Check config values as you would normally
var myConfig = new MyConfig();
configuration.Bind("MyConfigSection", myConfig);
if (myConfig.UseSentryLogging)
{
// configure the web host based on config
webBuilder.UseSentry();
}
});
});
var host = builder.Build();
await host.RunWithTasksAsync();
}
If you are configuring other services which can affect where configuration is read from, then you may find you need to store a reference to the IWebHostBuilder
and call ConfigureAppConfiguration
on the IHostBuilder
instead. Make sure you call ConfigureAppConfiguration
last so that the other configuration setup can take place first and you access it correctly:
public static async Task Main(string[] args)
{
// we store the reference to the webHostBuilder so we can access it outside of ConfigureWebHost
IWebHostBuilder _webBuilder = null;
var hostBuilder = Host.CreateDefaultBuilder(args);
var builder = hostBuilder
.ConfigureWebHostDefaults(webBuilder =>
{
// store the builder for later
_webBuilder = webBuilder;
webBuilder.UseStartup<Startup>();
})
.ReadConfigFromSomewhereElse()
.ConfigureAppConfiguration(configBuilder =>
{
// compile a temporary configuration instance
var configuration = configBuilder.Build();
// Check config values as you would normally
var myConfig = new MyConfig();
configuration.Bind("MyConfigSection", myConfig);
if (myConfig.UseSentryLogging)
{
// configure the web host based on config
_webBuilder.UseSentry();
}
});
var host = builder.Build();
await host.RunWithTasksAsync();
}
Note this is a little bit of a hack and so may not work in all cases.
You can clear the default sources added by CreateDefaultBuilder
then add a pre-built IConfiguration
with the AddConfiguration
extension method.
public static void Main(string[] args)
{
//...
var configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddCommandLine(args)
.AddJsonFile("appsettings.json")
.Build();
//Do something useful with the configuration...
var host = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(builder =>
{
builder.Sources.Clear();
builder.AddConfiguration(configuration);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.Build();
//...
}