IConfiguration in .NetCore

In this post I'm going to give an overview of IConfiguration in .NetCore and also give examples on how to set this up with a provider and how to use different files to override configuration values.

The full source code is available here. I will try and keep this up to date until .NetCore RTM (v1).

IConfiguration

The package can be found here: https://www.nuget.org/packages/Microsoft.Extensions.Configuration

This package contains the Interfaces and functionality for retrieving config values/sections.

Loading from different sources requires different packages which actually do the work of loading from a Configuration Source.
For example loading from a JSON file requires the package Microsoft.Extensions.Configuration.Json and from an XML file requires Microsoft.Extensions.Configuration.Xml.

If you wanted to get configuration from a SQL Database or HTTP endpoint - then you can write your own and plug them in.

Loading a Configuration File

I've chosen to load from a JSON file. I've added the Configuration package to my project and also the Configuration.Json package.

IConfigurationBuilder builder = new ConfigurationBuilder()  
                                    .AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();  
Getting a value

We've loaded a configuration file - now we want to get values out.

For a JSON file

{
    "Version": "1.0.0"
}

Get the value using

var version = configuration["Version"];  
Overriding Configuration values

This is where testing between environments becomes really easy. We don't want to be developing our application against live urls/dbs etc - so we want different configuration files depending on what environment we're running in.

What we can do is add another file (appsettings.development.json) to the Configuration builder which will override the values in appsettings.json. Visual Studio nicely groups these files for you in the Solution Explorer.

string environment = "development";  
IConfigurationBuilder builder = new ConfigurationBuilder()  
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{environment}.json", optional: true);
            IConfigurationRoot configuration = builder.Build();

The second AddJsonFile() overrides/adds to the first - so if we specify a section/value in both configuration files - the last added (appsettings.development.json in our case) will take precedence.

The optional: true means - if the runtime can't this file - don't throw an exception.

Example...

appsettings.json

{
    "ApiKey": "some-old-key"
}

appsettings.development.json

{
    "ApiKey": "my-dev-key"
}

Side note: do not store sensitive information in config files. Use User Secrets

Getting the ApiKey from configuration like so

var apiKey = configuration["ApiKey"];

Will give you

my-dev-key

Arrays

We have an array of values that we want from config.
Easy....

{
    "Auth": {
        "Users": [ "Steve", "Lucy", "Harry" ]
    }
}
IEnumerable<string> users = configuration.GetSection("Auth:Users").GetChildren().Select(x => x.Value);  

Gives us "Steve", "Lucy", "Harry"

Overriding Arrays

I've not yet found a way of overriding arrays "wholesale" - replacing an entire array with one from another config file. Instead we can only override individual items in the original.

For the Array in the example above, we can override individual items with the config file below

"Auth": {
    // Harry changes into Aliens sometimes
    "Users:2": "Alien"
  },

Using the string Users:2 we are explicitly overriding the third item in the (zero based) array.

You could even write it as one long "Config path"

{
    "Auth:Users:2": "Alien"
}

We make the call (in the example above) again to get the array of config values.

The result

"Steve", "Lucy", "Alien"

Adding to Arrays

We can use the same syntax as above to add items array - it's essentially the same. Instead of writing a Config path to an array index that exists - simply write the path to one that doesn't exist.

Again using the same "base config file" from above. We can add to the "Auth:Users" array like so:

{
   "Auth:Users:3": "Stacy"
}

The result of the array is now

"Steve", "Lucy", "Alien", "Stacy"

Conclusion

.NetCore configuration is very cool - it's much lighter than the old System.Configuration library. Plus it's been separated out - so now we can dependency inject our IConfiguration into classes which need it - without them having to care about the implementation of getting the config.

Drop me a tweet and let me know what you think, or if you've found out any other syntax I might have missed here - I'd love to know.

ryansouthgate

Software developer, living in Coventry, loves .Net, JavaScript and learning new languages.

Coventry