ASP.NET vNext: Optional Configuration Files

I’ve gotten pretty used to having a configuration loader in my Startup() constructor. Since beta5 is out now, the following code is in my Startup() constructor:

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
     var configBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath);

    configBuilder.AddJsonFile("config.json");
    configBuilder.AddJsonFile("config-local.json");
    configBuilder.AddEnvironmentVariables();

    Configuration = configBuilder.Build();
}

public static IConfiguration Configuration { get; private set; }

It’s fairly straight forward and understandable. First load config.json, then load config-local.json and then add in any environment variables. I can exclude config-local.json in my gitignore file and the world is good. I can access the Configuration object from anywhere using Startup.Configuration. (Someone will beat me up for not using Dependency Injection here – I’ll get to that tomorrow).

That is, until I check out the project from the repository and forget to add in the config-local.json file. Of course, one could argue that this is ok because the config-local.json file is meant to hold critical environment settings. I find I’d rather pop up a window saying “You haven’t configured me correctly” on the web interface is nicer than causing the code to blow up on Startup, especially when the code is likely to be running in the cloud.

You can, however, make the JSON files optional by adding a simple optional parameter:

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
    var configBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath);

    configBuilder.AddJsonFile("config.json", optional: true);
    configBuilder.AddJsonFile("config-local.json", optional: true);
    configBuilder.AddEnvironmentVariables();

    Configuration = configBuilder.Build();
}

This makes the configuration completely optional. It’s probably not the best idea to make both files optional. However, now you could set things up so that the database is a local-machine-only development database normally and only when it goes production do you get access to the SQL Server instance.

Better yet, you could pull the environment you are running on (by setting the ASPNET_ENV environment variable) and load a different config file for each environment:

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
    var configBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath);

    configBuilder.AddJsonFile("config.json", optional: true);
    configBuilder.AddJsonFile($"config-{env.EnvironmentName}.json", optional: true);
    configBuilder.AddEnvironmentVariables();

    Configuration = configBuilder.Build();
}

This is now my go-to configuration loader.