Gusztáv Varga bio photo

Gusztáv Varga

Catch me if you can

Email Twitter Facebook LinkedIn Github Stackoverflow

Overview


ASP.NET 5, being a complete redesign of the web stack from Microsoft, brings significant changes to the configuration system, too. This post quickly introduces the new capabilities through the most common usage scenarios by comparing them to the previous versions and provides some easy workarounds for reusing your already existing settings.

Core features

Let’s see the new features one by one. Just reference the core NuGet package, and import the Microsoft.Extensions.Configuration namespace to get started.

Configuration providers

ASP.NET 5 provides a much cleaner and more flexible way of declaring the sources of the configuration settings. Earlier, your only option was to define these values in the classic XML configuration files. Machine and application or folder level settings provided some extensibility, but these options were somewhat limited.

Consider your settings in JSON like:

You then define this as the source of your configuration:

Getting your standalone settings is as simple as:

Notice the use of the : character as the separator for the levels of the setting hierarchy. By the way, the keys used to retrieve the values are case-insensitive.

Of course, JSON is not the only option for loading your settings. Browse the available providers and reference the ones that you need, such as the XML file or environment variables.

Besides the flexibility the different file formats provide, an excellent addition is supporting the abstraction for using various types of sources like environment variables or command-line parameters. This pattern provides a clear separation between defining and using the different settings via the explicit step for “building” from the sources.

Environments

When multiple sources are set up as above, they are modeled internally as layers, in the order which they are declared when building the configuration. That is, when a setting is defined in multiple sources, the last one overwrites the previous ones.

As configuration transformations are not available, because the new system is not relying on XML anymore, this approach can be used to define settings for different environments effectively. Just create your baseline configuration and the differences for a given deployment.

Based on the application type, the environment itself can be identified by the host or, just like another layer of configuration, with the sources of your choice (e.g. command-line or environment variables).

Unfortunately, no generic mechanism exists yet for getting notified of the changes of any of the sources, but you can manually invoke Reload() for the already-built configuration any time.

Complex values

One of the most powerful new features is the ability to bind to complex types. By referencing the dedicated package you can easily load typed settings, even of those having complex hierarchies:

This approach also supports defining default values, simply by assigning them to the type itself in the constructors, for example.

With the options model, you can bring this to the next level, and use dependency injection to retrieve the settings. You can set up the related service, and then simply reference the settings you need.

Configuration for the application itself and the related unit tests, solved.

Reusing existing settings

As expected, it is also possible to define custom configuration providers to load the settings from any alternative sources you might have. These simple providers support loading settings from Octopus Deploy variables and classic XML configuration files.

Octopus Deploy variables

If you are already using Octopus for deployments, you probably also have some of your applications’ settings defined as variables. This provider, which also enables some centralized configuration scenarios, can be used to load the appropriate settings scoped to the current project, environment, and machine.

Using one of the projects of the demo server as a sample:

Demo variables

Variable substitution and scoping works as expected:

See the Wiki for more details.

Classic XML configuration files

Independently of how weird it is to lock an advanced abstraction to its legacy roots, by using these providers, you can easily load your existing Web.config, app.config or other custom files to wire up the application settings and connection strings in the new system.

The settings are equivalent with the JSON format above:

The values are loaded as follows:

See the Wiki for more details.

Summary

As described above, the new configuration system provides a clean, lightweight, and easily extensible framework for working with settings. Through custom providers, you can support centralized configuration scenarios and an alternative approach for managing secrets safely.

Resources