Click here to Skip to main content
15,886,518 members
Articles / Programming Languages / C#

How Does the Application settings in Core 3.1 Work in a Multi-environment Scenario

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
14 Mar 2021CPOL5 min read 12.1K   97   5  
Managing multiple environments is a very common situation in software development in the enterprise
Multiple environments are a very common situation in our process to develop software in the enterprise. NET Core 3.1 abandons the classic Web Config to use a .json file, but it goes beyond and gives the developer a very flexible way to configure the application in multiple environments. This article explores how Core manages this setting and how the developer can get the most out of this.

Introduction

Multiple environments are a very common situation in our process to develop software in the enterprise. NET Core 3.1 abandoning the classic Web Config to use a .json file, but it goes beyond and gives developers a very flexible way to configure the application in multiple environments. This article explores how Core manages this setting and how the developer can make the most out of it.

.NET Core 3.1 admits multiple AppSettings allowing us an easy configuration of the application in different environment. Each AppSetting file is differentiated for the other using the AppSettings.EnvironmentName.json convention.

Download Code demo

Background

Core organizes the AppSettings in the following form:

  • One Appsettings.json
  • Several optional AppSettings.environment.json

Image 1

Core manages these files in the following fashion:

  • The AppSettings.json is always taken into account to be used in the application.
  • Only one environment file is selected depending on the value of the .NET variable: ASPNETCORE_ENVIRONMENT

Image 2

This selected file is merged with the general AppSettings.json. In the merge, the following rules are applied:

  • All the values of both files go to the final settings.
  • If a value is in both files, the value of the environment setting file takes precedence and it is used in the application settings.

Image 3

Application Settings Example

Let's see a practical example. We have an AppSettings.json with two entries:

  • environment = default
  • var1 = default

and a AppSettings.dev.json with the following entries:

  • environment = dev-environment
  • var2 = dev

as you can see in the below image.

Image 4

If the ASPNETCORE_ENVIRONMENT variable has value of dev, then when we build the application, the AppSettings.dev.json is selected and merged with the AppSetting.json as is shown below:

Image 5

As result of this operation, the configuration variables are the following:

  • environment = dev-environment: because they are in both files and the value of dev takes precedence over the AppSettings.json
  • var1 = default: because it exists in Appsettings.json
  • var2 = dev: because it exists in AppSettings.dev.json

Using the Code

Download Code demo

To test this, you can use the project attached to this article. Let me briefly explain it.

The project is the simple API template for NET Core 3.1 APIs that you can find in Visual Studio(TM) 2019 that we modified to show best how the AppSettings works.

We added to the project three extra AppSettings files to be used in three different environment. This is a normal situation in a software developer company.

Image 6

Now we configure the environments with the following variables:

AppSettings.json

JavaScript
{
  "environment": "default",
  "var1": "default"
}

AppSettings.dev.json

JavaScript
{
  "environment": "dev-environment",
  "var2": "dev"
}

AppSettings.Development.json

JavaScript
{
  "environment": "Development",
  "var3": "development"
}

AppSettings.prod.json

JavaScript
{
  "environment": "Production",
    "var4": "production"
}

ApplSettings.qa.json

JavaScript
{
  "environment": "QA",
  "var5": "qa"
}

Note that we have the variable environment in each settings file and var1 to var5 only in one of the rest of the files.

We create a service in this application to read the configuration that the application uses when running. This allows us to know what is really used when the application is in operation.

C#
/// <summary>
 /// Get the real value of the settings
 /// </summary>
 /// <returns></returns>
 [HttpGet]
 [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
 public IActionResult Get()
 {
     string env = config["environment"];
     string var1 = config["var1"];
     string var2 = config["var2"];
     string var3 = config["var3"];
     string var4 = config["var4"];
     string var5 = config["var5"];

     string ret = Environment.NewLine;
     return Ok($"Environment: {env}{ret}var1:
     {var1}{ret}var2: {var2}{ret}var3: {var3}{ret}var4: {var4}{ret}var5: {var5}");
 }

Also, we create different profiles that allow us to launch the application using different values of ASPNETCORE_ENVIRONMENT:

C#
"API Prod": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "api/Configuration",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Prod"
      }
    },
    "API Dev": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "api/Configuration",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Dev"
      }
    },
    "API QA": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "api/Configuration",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "QA"
      }
    },

Build the application and see what happens when we launch the application using the profile Dev:

You should get this:

Environment: dev-environment
var1: default
var2: dev
var3: 
var4: 
var5: 

Observe that as we explain the variable Environment, that exists in AppSettings.json and in AppSettings.dev.json take the value of AppSettings.dev.json overriding the value present in AppsSettings.json. The var1 only exists in AppSettings.json and takes the value from there, and var2 only is present in AppSettings.dev.json and takes the value that is in there. Observe that var3, var4, and var5 have no value, because they are not present in any of the selected Appsettings.

If we run QA, the result will be different:

Environment: QA
var1: default
var2: 
var3: 
var4: 
var5: qa

You can continue to test, but it demonstrates how the final settings are built by the Core in the build process.

Points of Interest

As we see, all variables that you put in AppSettings.json should be used in all environment, except that the variable exists also in a AppSettings.environment.json.

One alternative of organizing our config is to put all values per defect in the AppSettings.json and to repeat in the other config those that change per environment. This organization appears attractive, but in my opinion leads to problems in real life.

My recommendation is to put in the AppSettings.json those values that are the same in all configurations. and put in AppSettings.environment.json, those values that change in every environment.

This allows you to get errors more easily, because you forgot to put a value, there is no default, and the service fails, given you have the chance to correct it.

If you take the value by defect, the program may still work, but with a false value creating confusing error when you deploy in the test environment that is used for several developers.

For example, you can point to a URL in production and other in QA, if you put the URL of QA in AppSettings.json and forgot to put in production, the program silently takes the QA values and you have no way to know if the configuration is correct.

If there are no values per defect, you can prevent that the program works with a defective configuration, for example, during the health check process, you can detect that the URL is not correct.

You can see more information about this in Video format at : https://youtu.be/cHgRF3bDKXU

History

  • 14th March, 2021: Initial version
  • Adding reference to Video

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Avalon Development
United States United States
Jose A. Garcia Guirado, Electronic Engineer, graduated in Havana/Cuba 1982, MCTS, MCSD.NET, MCAD.NET, MCSE. Worked in the Institute for Cybernetics and Mathematics of Academy of Science of Cuba for 8 years; since 1995 working as free software architect, developer and adviser, first in Argentina and from 2003 to 2010, in Germany as External consultant in DWS Luxembourg, AIXTRON AG and Shell Deutschland GmbH and from 2010 to 2012 in Mexico working for Twenty Century Fox, and Mexico Stock Exchange (BMV). From 2013 to now in USA, Florida, First in FAME Inc. and now as Senior Software Engineer in Spirit Airlines.

Comments and Discussions

 
-- There are no messages in this forum --