Configuration in ASP.NET 5

ASP.NET 5 offer a lot of options for loading configuration data such as json files, ini files, XML files, in memory collections, command line arguments, user secrets and environment variables.

The following has at least one example of each type of configuration. Configurations are setup in the constructor of the Startup class.

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
    // Setup configuration sources.
    var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
        .AddJsonFile("config.json")
        .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true)
        .AddIniFile("config.ini", optional: true)
        .AddInMemoryCollection(new Dictionary<string, string="">
        {
            {
            "AppSettings:TagLine",
            "InMemoryCollection"
            }
        })
        .AddXmlFile("config.xml", optional:true);

    if (env.IsDevelopment())
    {
        builder.AddUserSecrets();
    }
    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

As you can see from the example all the different configuration sources can be used together without any issues. A critical thing to keep in mind is if a configuration option is set in multiple places the last configuration source’s value will be used. For example, using the code above, if the title of a site was sent in config.json and config.ini then the value from config.ini would be used.

An example I have seen the ASP.NET team use many times is to use user secrets for API key when in development and then store the keys in environment variables for production.

Here are the relevant lines from the dependencies section of the project.json file.

"Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta7",
"Microsoft.Framework.Configuration.Json": "1.0.0-beta7",
"Microsoft.Framework.Configuration.UserSecrets": "1.0.0-beta7",
"Microsoft.Framework.Configuration.Xml" : "1.0.0-beta7"

Another great feature is being able to load an object with the values from a configuration section. The following is a class created to hold the settings for an application.

public class AppSettings
{
    public string Title { get; set; }
    public string TagLine { get; set; }
}

Then in the ConfigureServices function this is all that is needed to load the class.

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

Now instead of directly accessing the configuration classes in the HomeController the AppSettings class can be used instead. Here is an example of using ASP.NET 5’s built-in dependency to automatically get a reference to AppSetting via constructor injection.

private readonly IOptions _appSettings;

public HomeController(IOptions appSettings)
{
    _appSettings = appSettings;
}

And then using the _appSettings in the index action to pass values to the view.

public IActionResult Index()
{
    ViewData["Title"] = $"{_appSettings.Options.Title} - " +
                        $"{_appSettings.Options.TagLine}";
    return View();
}

The above is using C# 6’s new interpolated string feature.  The dollar sign before the string is what triggers the feature and allow use variables when wrapped in curly braces.

Check out this github repo for the internals of configuration in ASP.NET 5 .

I also recommend checking out the new Introduction to ASP.NET 5 course on Microsoft Virtual Academy. It covers a lot of good information including live.asp.net which is a production site used to for the ASP.NET 5 community stand up.

4 thoughts on “Configuration in ASP.NET 5”

  1. Is there an example of a pattern somewhere that shows another class being injected via DI consuming the appsettings?

    i.e. my controller takes an IDataMover. I’d like the concrete DataMover class to have an IOptions _appsettings it gets via DI – but I get runtime errors in that case – DI fails to create the datamover because it can’t instantiate an IOptions…

    Thanks – good article

    1. Kevin I would think what you are trying to do would work. What is the error you are getting?

      Have you tried stepping through the constructors of the classes being injected?

      If that doesn’t give you any help I would try pulling the the framework code from github and stepping through it.

      Passed that if you want to share the code I can take a look at it.

      1. Thanks. I’ve fallen back to thinking I had a build issue. I’ve built a stubbed equivalent class that worked; transplanted the functionality into it, and it worked perfectly – so clearly I had something subtle wrong in the prior version.

        I’m now doing a compare to see where I went awry. Thanks for taking the time to follow up, but I seem to have gotten something subtle wrong, that I didn’t in a rewrite.

        Off to diff.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.