ASP. NET CORE supports multiple Appsettings.json based on environment variables

Source: Internet
Author: User

0. Background

In the process of developing the project, the configuration of the production environment and the debugging environment must be different. In the simplest case, such as a connection string, the debug environment must not be able to connect to the production database. In the previous case, this can only be done by you COPY the two configuration file with the same name. Then you use the local configuration locally, and the production environment uses the production environment configuration file, which is cumbersome.

While ASP. NET CORE supports the use of environment variables to dynamically configure JSON files, here's a look.

1. Preparatory work

First add a file to your ASP. NET CORE Project appsettings.json with the following content:

{  "ConnectionString": {    "Default": "Normal Database"  }}

Then continue adding one appsettings.Development.json , and you'll see the following in your solution manager.

Change its contents as follows:

{  "ConnectionString": {    "Default": "Development Database"  }}

After that, we continue to add a production environment configuration file, named appsettings.Production.json , to change its contents as follows:

{  "ConnectionString": {    "Default": "Production Database"  }}

Finally, our documents should be as follows:

The above is our preparation, we have prepared two environment configuration files and a default configuration file, below I will see how to apply environment variables to achieve the effect we want.

2. Environmental control

In the project debugging, we can right-click the project properties, jump to debug can see an environment variable settings, change ASPNETCORE_ENVIRONMENT the value to switch between different environments.

We can see that currently we are in the Development development environment, then according to our assumptions, we should read appsettings.Development.json the file data.

2. Writing code

Create a new AppConfigure static class with a dictionary inside it that caches configurations for different paths in different environments IConfigurationRoot .

public static class AppConfigure{    // 缓存字典    private static readonly ConcurrentDictionary<string, IConfigurationRoot> _cacheDict;    static AppConfigure()    {        _cacheDict = new ConcurrentDictionary<string, IConfigurationRoot>();    }    // 传入 JSON 文件夹路径与当前的环境变量值    public static IConfigurationRoot GetConfigurationRoot(string jsonDir, string environmentName = null)    {        // 设置缓存的 KEY        var cacheKey = $"{jsonDir}#{environmentName}";        // 添加默认的 JSON 配置        var builder = new ConfigurationBuilder().SetBasePath(jsonDir).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);        // 根据环境变量添加相应的 JSON 配置文件        if (!string.IsNullOrEmpty(environmentName))        {            builder = builder.AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true);        }        // 返回构建成功的 IConfigurationRoot 对象        return builder.Build();    }}

The use of the words is also very simple:

public Startup(IHostingEnvironment env){    var configurationRoot = AppConfigure.GetConfigurationRoot(env.ContentRootPath, env.EnvironmentName);    Console.WriteLine(configurationRoot["ConnectionString:Default"]);}
3. Testing

If you change the environment variable directly, you can see the effect and change its value to Production.

Now let's run and add a watch variable.

It seems that it is now reading the data of our production environment.

4. Code Analysis

In fact, it is not so troublesome, in the Startup.cs structure of the injection IConfiguration is GetConfigurationRoot() built according to this method, you directly use Configuration/ConfigurationRoot the indexer can access to the environment variable corresponding to the JSON file.

Perhaps you do not understand, obviously in the GetConfigurationRoot() method of using the AddJsonFile() method only added two times a Provider, why use the indexer to access the JSON configuration is used in the current environment of the JSON file?

I actually thought that the first. NET CORE for IConfiguration the indexer implementation is to read the current environment variables, and then according to the environment variable to match the corresponding Provider to get the value.

Finally looked through the source code of. NET CORE and found that I was wrong, in fact, he is simply flipping the Providers collection, and then take the first element.

Copyright (c). NET Foundation. All rights reserved.//Licensed under the Apache License, Version 2.0. See License.txt in the project root for License information.using system;using system.collections.generic;using system.li    Nq;using system.threading;using Microsoft.extensions.primitives;namespace microsoft.extensions.configuration{        public class Configurationroot:iconfigurationroot {private ilist<iconfigurationprovider> _providers;        Private Configurationreloadtoken _changetoken = new Configurationreloadtoken ();        Incoming configuration provider public configurationroot (ilist<iconfigurationprovider> providers) when initializing Configurationroot            {if (providers = = null) {throw new ArgumentNullException (nameof (providers));            } _providers = providers;                foreach (var p in providers) {p.load (); Changetoken.onchange (() = P.getreloadtoken (), () = RaisechanGed ());        }} public ienumerable<iconfigurationprovider> Providers = _providers; public string this[string key] {get {//Invert Providers, then traverse fo Reach (var provider in _providers.                   Reverse ()) {string value; If you get the value, return directly and no longer traverse if (provider.                    Tryget (key, out value)) {return value;            }} return null; } set {if (!_providers.                Any ()) {throw new InvalidOperationException (resources.error_nosources); } foreach (var provider in _providers) {provider.                Set (key, value); }            }        }    }    // ... Omitted code}

Back to the third section of the code, you can see that we first add appsettings.json and then add to the environment variables $"appsettings.{environmentName}.json" , so after the reversal is definitely a configuration file with environment variables.

5. Environment variable configuration for different OS 5.1 Windows

Directly right-click the computer to manually add environment variables.

5.2 Linux

Use the Export command to set the environment variable directly.

export ASPNETCORE_ENVIRONMEN='Production'
5.3 Docker

The Docker configuration is the simplest, adding parameters directly to the boot container -e , such as:

docker run -d -e ASPNETCORE_ENVIRONMEN=Production --name testContainer testImage

ASP. NET CORE supports multiple Appsettings.json based on environment variables

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.