Environment name in ASP.NET Core 1.0 RC2

Why is it Production and how can I change it?

 May 29, 2016


So, your new web app. is ready for QA and you have all your app. settings neatly separated using appsettings files. But, when you launch the app. on your brand new server, you know something is wrong and quickly realize the app. just loaded production settings. How do you correct this problem? There are several ways and they all involve setting the hosting environment's environment-name.

Where does the environment name get used?

If you are following convention and have a Startup class, then the constructor receives an IHostingEnvironment-instance. This will contain a property named EnvironmentName. You might use this to load specific app. settings:

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }
}

Where does the environment name come from?

Again, if you are following convention, inside your Program.Main method, you will have constructed a WebHostBuilder instance. The instance's constructor will construct a HostingEnvironment instance. The latter sets the default-value for the environment name (i.e. Production).

But wait, there's more!

Also inside the WebHostBuilder constructor, there is a section which loads one of several possible EnvironmentKey-values. These are defined as environment variables on your host machine:

Linux

> export ASPNETCORE_ENVIRONMENT="QA"

If the former is not defined, the following legacy-key (RC1) is tried:

> export ASPNET_ENV="QA"

Are we there yet?

Almost. Once you call Build on your WebHostBuilder instance, this initializes the HostingEnvironment instance and allows any configuration passed into WebHostBuilder one last chance to set the environment name prior to adding the HostingEnvironment instance into the services collection for consumption in Startup.

Example Program.Main

public class Program
{
    public static void Main(string[] args)
    {
        var config = new ConfigurationBuilder()
            .AddCommandLine(args)
            .Build();

        var host = new WebHostBuilder()
            .UseConfiguration(config)
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

In this case, we can now set the environment as a command-line argument:

> dotnet run --environment="QA"
Hosting environment: QA
Now listening on: http://localhost:5000

Helpers

There are several helper-methods which can be found in Microsoft.AspNetCore.Hosting.Abstractions for checking the current environment name:

public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        if (env.IsDevelopment())
        {
            // do stuff on your local machine
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }

        if (env.IsStaging())
        {
            // do stuff on your pre-prod. machine
        }

        if (env.IsProduction())
        {
            // do stuff on your prod. machine
        }

        if (env.IsEnvironment("QA"))
        {
            // do stuff on your QA machine
        }
    }
}

Conclusion

Hopefully you now have a better understanding of the inner-workings behind environment name. There are several ways to define your app.'s environment name. You could set it globally with an environment variable or keep it app.-specific and leverage command-line arguments. Either way, without defining it, you are guaranteed a default-value and do not have to worry about null-values (unless you set it to null).