Configuration Providers

NOTE: This article has been edited 16-10-2015 to line up with ASP.NET 5 beta8 latest changes

Application configuration so common task that designers of new .NET decided that it will be one of the central components. There are many configuration providers available to use out of the box with DNX. Configuration is loaded as a hierarchy and programmer has control over the sources and the order of loading process. This comes in handy as a standardized way of handling repeatable task.

With feature complete 1.0.0-beta8 release I feel that it is the right time to take a closer look at Microsoft.Framework.Configuration namespace that enhance DNX environment. There are already some very good posts made on this topic including Louis DeJardin ASP.NET vNext Moving Parts: IConfiguration and Jsinh ASP.NET 5 Configuration – Microsoft Framework ConfigurationModel so if you have not already seen them you may be interested later for reference – they are a little outdated due to the changes and ironing process in DNX.

What has been changed ?

Most notably configuration file is not loaded and read implicitly along with assembly but application has full control over what and when is loaded. In full .NET framework all settings had to be enclosed in app.config or web.config so any configuration that was available only on runtime or originating from other sources like .ini files had to be handled differently.

Another scenario that was somewhat painful was having multiple environments. Although two staged setup with Production and Dev worked well by using web.config transformations, having multiple stage environments caused explosion of approaches in the community. This problem was addressed by allowing application authors load configs conditionally.

To the point

The new configuration is distributed in NuGet packages Microsoft.Framework.Configuration.* (later it will be Microsoft.Extensions.Configuration.* as with commit ). Using each extension forces you to import different NuGet package.

Currently there are six out-of-the-box available class extensions to IConfigurationBuilder interface provided by Microsoft team.

MemoryConfigurationExtensions

Often it is worth to add default values to your configuration so that if necessary they will be overwritten by other sources.

NOTE: at any point you may decide to overwrite any configuration simply by using setter eg. configuration["Title"] = "other string". And before you ask – no you can NOT set this way complex JSON objects.

JsonConfigurationExtensions

One of the most common configuration scenarios in DNX is reading from JSON file. Example file look like this:

Config files can be possibly deep hierarchical objects. Syntax for accessing nested elements is root:nested1:nested2.

To enable finding “config.json” ConfigurationBuilder must be provided with base path for the application by calling SetBasePath. In ASP.NET 5 this path can be taken from IApplicationEnvironment object injected by the framework to Startup class.

It is also common to include additional config files based on Environment and making them optional if needed.

EnvironmentVariablesExtensions

Fairly straightforward method of overwriting configuration in various environments is setting environment variable. This is especially useful in Azure where deployment is easy and application downtime should be minimal.

addsettings

Adding environment variables to your configuration is made by calling AddEnvironmentVariables extension method on IConfigurationBuilder. To prevent loading all variables or target subset of variables (eg. for specific application) prefix can be added as a AddEnvironmentVariables first parameter. This prefix will be removed from final configuration key.

Example:

Running set PG_ConsoleApp:Feed=myget.org in command line and then dnx run on the following code results in printing a feed name.

IniConfigurationExtensions

Example .ini file:

Values are stored in section:key keys so retrieving them is performed like this:

Lines starting with ‘;’, ‘#’ or ‘/’ are treated as comments and ignored. Values can have double quotes which are trimmed during parsing process.

XmlConfigurationExtensions

Using XML configuration file is very similar to other file based configuration sources. Important note here is that reading configuration does not understand old-style web.config so for example do not expect it to set values in ConfigurationManager.ConnectionStrings property automatically.

CommandLineConfigurationExtensions

Command line options can be passed by starting application using dnx run YOUR_ARGUMENTS. This type of configuration may be very helpful in Command Line apps or while creating custom command (like Entity Framework has ef). Full example can be downloaded here where I show how to create custom command:

For some more flexibility it is also possible to map switches to give them short and long names. To avoid confusion map switch value should be different than any other key or value.

Now following are equivalent (slash / is replaced by -- while parsing):

and will result in output:

Summary

New mechanisms for configuration is a step in a decent direction. Application authors get common and extensible way of handling configuration. This is also great simplification of the model introduced in full .NET and I feel it very personally – honestly I have never remembered how to inherit from IConfigurationSectionHandler or ConfigurationSection and implement it properly without just copying existing example.

Basing on the classes described here this idea is extended to simplify configuration even further. In ASP.NET MVC 6 IServiceCollection interface is passed into Startup.ConfigureServices method and used to prepare configuration injection for your own use. But this is topic on another entry.

3 Comments

  1. Can’t get this to work in a standalone class library. Is that not possible since the configuration needs to be initialized at program start? Otherwise I will go back to old csproj type of library.

  2. i’ve successfully setup a configuration including monitoring the related json file, like

    Configuration = builder.Build().ReloadOnChanged(“appsettings.json”);

    questions:
    1: how to observe other providers if any (multiple files)

    2: actually reload is working, but it’s not reflected to the Optionsmodel (strongly typed approach), how to achieve that?

    3: how to be informed about a config changes in a ‘kind of central place’ to take some further actions (Server restart, etc.)

Leave a Reply