This short post is in response to a comment I received on a post I wrote a while ago, about how to set the hosting environment in ASP.NET Core. It's a question I've heard a couple of times, so thought I'd write it up here.
Do you know if there is a way to overwrite environment variable name? For example, I want my CoolProject to take environment name not fromASPNETCORE_ENVIRONMENT
but fromCOOL_PROJ_ENV
. Is it possible?
The answer to that question is a little nuanced. If you already have an app deployed, and want to switch the environment for it without changing other apps on that machine, then you can't do it with Environment variables. Those obviously affect the whole environment!
tl;dr; Create a custom configuration object in your Program.cs file, load the environment variable using a custom key, and callUseEnvironment
on theWebHostBuilder
.
However, if this is a capability you think you will need, you can use a similar approach to the one I use in that post to set the environment using command line arguments.
This approach involves building a new
IConfiguration
object, and passing that in to the WebHostBuilder
on application startup. This lets you load configuration from any source, just as you would in your normal startup method, and pass that configuration to the WebHostBuilder
using UseConfiguration
. The WebHostBuilder
will look for a key named "Environment"
in this configuration, and use that as the environment.
For example, if you use the following configuration.
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
You can pass any setting value with this setup, including the "environment variable":
> dotnet run --environment "MyCustomEnv"
Project TestApp (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Hosting environment: MyCustomEnv
Content root path: C:\Projects\Repos\MyCoolProj\src\MyCoolProj
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
This is fine if you can use command line arguments like this, but what if you want to use environment variables? Again, the problem is that they're shared between all apps on a machine.
However, you can use a similar approach, coupled with the
UseEnvironment
extension method, to set a different environment for each machine. This will override the ASPNETCORE_ENVIRONMENT
value, if it exists, with the value you provide for this application alone. No other applications on the machine will be affected.public class Program
{
public static void Main(string[] args)
{
const string EnvironmentKey = "MYCOOLPROJECT_ENVIRONMENT";
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseEnvironment(config[EnvironmentKey])
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
To test this out, I added the
MYCOOLPROJECT_ENVIRONMENT
key with a value of Staging
to the launch.json file VS uses when running the app:{
"profiles": {
"EnvironmentTest": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"MYCOOLPROJECT_ENVIRONMENT": "Staging"
},
"applicationUrl": "http://localhost:56172"
}
}
}
Running the app using F5, shows that we have correctly picked up the
Staging
value using our custom environment variable:Hosting environment: Staging
Content root path: C:\Users\Sock\Repos\MyCoolProj\src\MyCoolProj
Now listening on: http://localhost:56172
Application started. Press Ctrl+C to shut down.
With this approach you can effectively have a per-app environment variable that you can use to configure the environment for an app individually.
Summary
On shared hosting, you may be in a situation when you want to use a different
IHostingEnvironment
for multiple apps on the same machine. You can achieve this with the approach outlined in this post, building an IConfiguration
object and passing a key to WebHostBuilder.UseEnvironment
extension method.