I spent quite a while trying to work out the best thing for me to do in this situation.
I ended up taking the code from Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder and adding the .UseEnvironment extension on the builder.
builder.UseEnvironment(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development");
I default to Development rather than the generally preferred Production, but that was personal preference.
It is limited and if you want to be clever and check for commandline arguments etc and so forth, feel free. It's a place to start.
public static IHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new HostBuilder();
// This line has been added to read the environment variable.
builder.UseEnvironment(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development");
builder.UseContentRoot(Directory.GetCurrentDirectory());
builder.ConfigureHostConfiguration(config =>
{
config.AddEnvironmentVariables(prefix: "DOTNET_");
if (args != null)
{
config.AddCommandLine(args);
}
});
builder.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
// IMPORTANT: This needs to be added *before* configuration is loaded, this lets
// the defaults be overridden by the configuration.
if (isWindows)
{
// Default the EventLogLoggerProvider to warning or above
logging.AddFilter<EventLogLoggerProvider>(level => level >= Microsoft.Extensions.Logging.LogLevel.Warning);
}
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
if (isWindows)
{
// Add the EventLogLoggerProvider on windows machines
logging.AddEventLog();
}
})
.UseDefaultServiceProvider((context, options) =>
{
var isDevelopment = context.HostingEnvironment.IsDevelopment();
options.ValidateScopes = isDevelopment;
options.ValidateOnBuild = isDevelopment;
});
return builder;
}
EnvironmentName
is only set when the contents of the environment variable are recognized – Panagiotis KanavosDev
means so the correct behavior would be to default to production - or throw. – Panagiotis KanavosASPNETCORE_ENVIRONMENT
in yourlaunchSettings.json
. – Kirk Larkin