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();
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);
"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.
comments powered by Disqus