The New Configuration Model in ASP.NET Core

ASP.NET Core has a lot of changes compared with the others versions of ASP.NET. One change I want to highlight is the new way to configure settings. With previous versions, this configuration was made by using the common file web.config, but this file simply doesn’t exist anymore in ASP.NET Core. Instead, a new easy way to declare and access to the settings is provided. Let’s take a look.

// “The New Configuration Model in ASP.NET Core” is one of our top 5 .NET articles of 2017. See the full list here.

Goodbye web.config

Before we examine the new way to configure settings, let’s look at how it was done in versions prior to ASP.NET Core.

First, you go to the web.config file and, inside the appsettings node, add all the settings that you need. This works like a key-value dictionary:

<appSettings>
    <add key="SmtpServer" value="0.0.0.1" />
    <add key="SmtpUser" value="user@company.com" />
    <add key="SmtpPass" value="12345678" />
    <add key="SmtpPort" value="25" />
    <!-- More Settings -->
</appSettings>

The next step is to access these values. This is done using the ConfigurationManager class:

ConfigurationManager.AppSettings["SmtpServer"];

Hello appsettings.json

In ASP.NET Core, it is possible to read settings from different sources like XML, JSON and INI files. To see how it works in your ASP.NET Core Application, add a new section to store the SMTP info in the appsettings.json file:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Verbose",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "Smtp": {
    "Server": "0.0.0.1",
    "User": "user@company.com",
    "Pass": "123456789",
    "Port": "25"
  }
}

One of the key advantages in this new configuration model is that it’s easy to create a class to work with the data. To do that for the example above, create a new class called SmtpConfig inside the folder ViewModels (or whatever folder you prefer) and define four properties:

public class SmtpConfig
{

    public string Server { get; set; }
    public string User { get; set; }
    public string Pass { get; set; }
    public int Port { get; set; }
}

Next, go to the Startup.cs class, add the following code within the constructor to read the appsettings.json file:

var builder = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .AddEnvironmentVariables();
Configuration = builder.Build();

In the same class, go to the ConfigureServices function. The following code will read the Smtp section, then use the Configure method of Services to set this to the SmtpConfig class:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));
    services.AddMvc();
    //Other services
}

Using Configuration

ASP.NET Core has built-in dependency injection. To use the SmtpConfig class, you can inject them using the Interface IOptions<T>. The following examples usesthis in a MVC Controller:

public class HomeController : Controller
{
    public SmtpConfig SmtpConfig { get; }
    public HomeController(IOptions<SmtpConfig> smtpConfig)
    {
        SmtpConfig = smtpConfig.Value;
    }
    //Action Controller
}

Looking at the constructor, you’ll see that it’s injecting an object of type SmtpConfig through IOptions<SmtpConfig> and assigning it to a property of the same type:

settingsaspnetcore

All’s good and pretty easy.

Configuring Multiple Environments

What if you need different configuration values for different environments? If you remember web.config transformations, there is a similar concept here that is related to determining the environment (dev, QA, staging, production, etc). Let’s see how it works.

Add a new JSON file and set the name appsettings.qa.json then add only the smtp section

with the values associated with this new environment:

{
    "Smtp": {
        "Server": "0.0.0.5",
        "User": "usersmtp@company.com",
        "Pass": "Ke!2546hg#$",
        "Port": "427"
    }
}

So how does the framework know what the current environment is? There is an environment variable called Hosting:Environment. To access it inside Visual Studio, open the project properties, go to the Debug tab and change the value for this variable to qa:

Project Properties

Return to Startup.cs class and next to the line that read the appsettings file, tell the framework to read the additional appsettings file base on the environment. If this file exists, the property values are overridden:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}

Test the application again, and look the values that are used this time:

QA Settings

Conclusion

APS.NET Core offers a new configuration model that is clean and very easy to use. Plus it works with XML, it works with JSON, INI and any other file type you may need. Lastly, it is very customizable and is built with dependency injection in mind.

Comments