ASP .NET CORE 根据环境变量支持多个 appsettings.json
0.背景
在开发项目的过程当中,生产环境与调试环境的配置肯定是不一样的。拿个最简单的例子来说,比如连接字符串这种东西,调试环境肯定是不能连接生产数据库的。在之前的话,这种情况只能说是你 COPY 两个同名的配置文件来进行处理。然后你在本地就使用本地的配置,生产环境就使用生产环境的配置文件,十分麻烦。
而 ASP .NET CORE 支持利用环境变量来动态配置 JSON 文件,下面就来看一下吧。
1.准备工作
首先在你的 ASP .NET CORE 项目当中添加一个 appsettings.json 文件,内容如下:
{
"ConnectionString": {
"Default": "Normal Database"
}
}
之后再继续添加一个 appsettings.Development.json,之后在你的解决方案管理器就会看到下面这种情况。

更改其内容如下:
{
"ConnectionString": {
"Default": "Development Database"
}
}
之后呢,我们继续添加一个生产环境的配置文件,名字叫做 appsettings.Production.json ,更改其内容如下:
{
"ConnectionString": {
"Default": "Production Database"
}
}
最后我们的文件应该如下图:

以上就是我们的准备工作,我们准备了两个环境的配置文件以及一个默认情况的配置文件,下面我就就来看看如何应用环境变量来达到我们想要的效果。
2.环境控制
在项目调试的时候,我们可以通过右键项目属性,跳转到调试可以看到一个环境变量的设定,通过更改 ASPNETCORE_ENVIRONMENT 的值来切换不同环境。

可以看到目前我们处于 Development 也就是开发环境,那么按照我们的设想,就应该读取 appsettings.Development.json 的文件数据了。
2.编写代码
新建一个 AppConfigure 静态类,他的内部有一个字典,用于缓存不同环境不同路径的 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();
}
}
用法的话也很简单:
public Startup(IHostingEnvironment env)
{
var configurationRoot = AppConfigure.GetConfigurationRoot(env.ContentRootPath, env.EnvironmentName);
Console.WriteLine(configurationRoot["ConnectionString:Default"]);
}
3.测试
测试的话直接更改环境变量就可以看到效果了,更改其值为 Production。

现在我们来运行,并且添加一个监视变量。

看样子它现在读取的就是我们的生产环境的数据了。
4.代码分析
其实吧,也不用这么麻烦,在 Startup.cs 通过构造注入得到的 IConfiguration 就是按照 GetConfigurationRoot() 这个方法来进行构建的,你直接使用 Configuration/ConfigurationRoot 的索引器就可以访问到与环境变量相应的 JSON 文件了。
可能你还不太理解,明明在 GetConfigurationRoot() 方法里面使用 AddJsonFile() 方法只是添加了两次个 Provider ,为什么在使用索引器访问 JSON 配置的时候就是使用的当前环境的 JSON 文件呢?
我其实以为最开始 .NET CORE 对于 IConfiguration 的索引器实现就是读取了当前环境变量,然后根据这个环境变量去匹配对应的 Provider 取得值。
最后翻阅了 .NET CORE 的源代码之后发现是我想错了,其实他就是单纯的翻转了一下 Providers 的集合,然后取的第一个元素。
// 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.Linq;
using System.Threading;
using Microsoft.Extensions.Primitives;
namespace Microsoft.Extensions.Configuration
{
public class ConfigurationRoot : IConfigurationRoot
{
private IList<IConfigurationProvider> _providers;
private ConfigurationReloadToken _changeToken = new ConfigurationReloadToken();
// 初始化 ConfigurationRoot 的时候传入配置提供者
public ConfigurationRoot(IList<IConfigurationProvider> providers)
{
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
{
// 反转 Providers ,之后遍历
foreach (var provider in _providers.Reverse())
{
string value;
// 如果拿到了值,直接返回,不再遍历
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);
}
}
}
}
// ... 省略了的代码
}
回到第三节所写的代码,可以看到我们首先添加的是 appsettings.json 然后再根据环境变量添加的 $"appsettings.{environmentName}.json" ,所以反转之后取得的肯定就是带环境变量的配置文件咯。
5.不同 OS 的环境变量配置
5.1 Windows
直接右键计算机手动添加环境变量。


5.2 Linux
使用 export 命令直接进行环境变量设置。
export ASPNETCORE_ENVIRONMEN='Production'
5.3 Docker
Docker 配置最为简单,直接在启动容器的时候加上 -e 参数即可,例如:
docker run -d -e ASPNETCORE_ENVIRONMENT=Production --name testContainer testImage
ASP .NET CORE 根据环境变量支持多个 appsettings.json的更多相关文章
- ASP.NET Core 根据环境变量支持多个 appsettings.json配置文件 (开发和生产)
新建一个项目,web根目录会出现一个 appsettings.json 配置文件, 此时添加--新建项,输入 appsettings.Development.json 再新增一个,appsetti ...
- 在ASP.NET Core配置环境变量和启动设置
在这一部分内容中,我们来讨论ASP.NET Core中的一个新功能:环境变量和启动设置,它将开发过程中的调试和测试变的更加简单.我们只需要简单的修改配置文件,就可以实现开发.预演.生产环境的切换. A ...
- ASP.NET Core配置环境变量和启动设置
在这一部分内容中,我们来讨论ASP.NET Core中的一个新功能:环境变量和启动设置,它将开发过程中的调试和测试变的更加简单.我们只需要简单的修改配置文件,就可以实现开发.预演.生产环境的切换. A ...
- [转]ASP.NET Core配置环境变量和启动设置
本文转自:https://www.cnblogs.com/tdfblog/p/Environments-LaunchSettings-in-Asp-Net-Core.html 在这一部分内容中,我们来 ...
- ASP.NET Core使用环境变量
前言 通常在应用程序开发到正式上线,在这个过程中我们会分为多个阶段,通常会有 开发.测试.以及正式环境等.每个环境的参数配置我们会使用不同的参数,因此呢,在ASP.NET Core中就提供了相关的环境 ...
- .NET CORE学习笔记系列(3)——ASP.NET CORE多环境标识
在开发项目的过程当中,生产环境与调试环境的配置是不一样的.比如连接字符串. ASP .NET CORE 支持利用环境变量来动态配置 JSON 文件.ASP.NET Core 引用了一个特定的环境变量 ...
- 图解 ASP.NET Core开发环境准备
2016年6月28日微软宣布发布 .NET Core 1.0.ASP.NET Core 1.0 和 Entity Framework Core 1.0. .NET Core是微软在两年前发起的开源跨平 ...
- ASP.NET Core Windows 环境配置 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Windows 环境配置 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Windows 环境配置 ASP.NET Core ...
- windows/Linux下设置ASP.Net Core开发环境并部署应用
10分钟学会在windows/Linux下设置ASP.Net Core开发环境并部署应用 创建和开发ASP.NET Core应用可以有二种方式:最简单的方式是通过Visual Studio 2017 ...
随机推荐
- 初学C的感想
既然是随笔,那就让我谈谈或者说聊聊自己的感想吧.刚刚进入大学的时候,对物联网工程这个专业挺迷茫的,至少我不知道自己将要学什么,只知道高数和英语是一定要学的,后来听学长说要学C语言,对这个概念很陌生,有 ...
- ----regular expression in js----
正则表达式:Regular Expression,在代码中常简写为regex.regexp或RE)使用单个字符串来描述.匹配一系列符合某个句法规则的字符串搜索模式. 搜索模式可用于文本搜索和文本替换. ...
- 结果集ResultSet
我们访问数据库时候经常见到这样遍历结果集 conn = DBHelper.getConnection(); String sql = "select * from items"; ...
- 别人的Linux私房菜(20)启动流程、模块管理与Loader
系统启动时,首先加载BIOS,通过BOIS读取COMS的硬件信息,进行自我检测,取得第一个可启动的设备(多个根据设置有关). 读取并执行设备内的MBR启动引导程序,引导程序调用boot sector中 ...
- SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页
SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页 **SpringBoot+Mybatis使用Pagehelper分页插件自动分页,非常好用,不用在自己去计算和组装了. ...
- 破解某普通话测试app会员
设备要求 已root的Android手机 软件要求 反编译工具 jeb.APK改之理(APK IDE) hook工具 frida.xposed. 布局分析工具 Android Device Monit ...
- ABAP 常见系统表
TRDIRT Program nameTFTIT Function module nameDD02T Table name
- web应用与web框架
一.web应用 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. import socket def handle_request(client ...
- Geomystery现已上架!
欢迎体验由王涵.程立智.郑昊.蔡镇泽.李明伦.温志成同学开发的几何解谜游戏Geomystery,现已上架Microsoft官方商城! https://www.microsoft.com/zh-cn/s ...
- python基础自学 第三天
变量的命名 01.标识符和关键字 标识符 标识符就是程序员定义的变量名.函数名. 标识符可以由字母,下划线,和数字组成. 不能以数字开头 不能与关键字重名 关键字 就是在python内部已经使用的标识 ...