ASP.NET Core(十)Configuration 配置优先级详解

ASP.NET Core 项目启动,默认执行顺序为:宿主 Host -> 读取配置 -> 日志设置 -> 注册服务(DI)-> 添加中间件 -> WebHost 监听 -> 后台 Work 启动。

配置的加载和读取是在启动流程的最前面。微软关于 ASP.NET Core 中的配置文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-6.0

Host.CreateDefaultBuilder 方法中,按照以下顺序为应用提供默认配置:

  • ChainedConfigurationProvider:添加现有的 作为源。在默认配置示例中,添加主机配置,并将它设置为应用配置的第一个源。

  • 使用 appsettings.json的 appsettings.json。

  • 使用 JSON 配置提供程序通过 appsettings..json 提供。例如,appsettings.Production.json 和 appsettings.Development.json。

  • 应用在 环境中运行时的应用机密。

  • 使用环境变量配置提供程序通过环境变量提供。

  • 使用命令行配置提供程序通过命令行参数提供。

源码如下:

public static IHostBuilder CreateDefaultBuilder(string[] args)
        {
            var builder = new HostBuilder();

            builder.UseContentRoot(Directory.GetCurrentDirectory());
            builder.ConfigureHostConfiguration(config =>
            {
                config.AddEnvironmentVariables(prefix: "DOTNET_");
                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            });

            builder.ConfigureAppConfiguration((hostingContext, config) =>
            {
                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

                if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
                {
                    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                    if (appAssembly != null)
                    {
                        config.AddUserSecrets(appAssembly, optional: true);
                    }
                }

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureLogging((hostingContext, logging) =>
            {
                var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

                // IMPORTANT: This needs to be added *before* configuration is loaded, this lets
                // the defaults be overridden by the configuration.
                if (isWindows)
                {
                    // Default the EventLogLoggerProvider to warning or above
                    logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
                }

                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
                logging.AddDebug();
                logging.AddEventSourceLogger();

                if (isWindows)
                {
                    // Add the EventLogLoggerProvider on windows machines
                    logging.AddEventLog();
                }
            })
            .UseDefaultServiceProvider((context, options) =>
            {
                var isDevelopment = context.HostingEnvironment.IsDevelopment();
                options.ValidateScopes = isDevelopment;
                options.ValidateOnBuild = isDevelopment;
            });

            return builder;
        }

源码地址:https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Host.cs

a87f696fd30e19ee7ddbfeae7e31e4c8.png

通过代码可以看出,程序获取配置优先级依次为:appsettings.json -> appsettings.环境.json -> 环境变量 -> 命令行参数。我们根据优先级进行测试。

新建一个控制台方法返回所有配置信息,代码如下:

private readonly ILogger<HomeController> _logger;

        public IConfiguration _configuration { get; }

        public HomeController(ILogger<HomeController> logger, IConfiguration configuration)
        {
            _logger = logger;
            _configuration = configuration;
        }

        public IActionResult Index()
        {
            return Json(_configuration.AsEnumerable());
        }

首先,appsettings.json 配置文件,如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "WebConfig": {
    "Name": "itsvse.com",
    "Date": "2021"
  }
}

 新建 appsettings.Test.json 配置,如下:

{
  "WebConfig": {
    "Name": "itsvse.com test"
  }
}

尝试启动项目,查看 WebConfig:Name 和 WebConfig:Date 的配置,如下图:

ee3395f303e7f1400e1381415c53e332.png

找到 Properties -> launchSettings.json 文件,修改 ASPNETCORE_ENVIRONMENT 环境配置为 Test,如下:

"IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Test"
      }
    }

这时程序会读取 appsettings.Test.json 的配置,尝试重新启动项目,发现 WebConfig:Name 已经覆盖了,如下图:

b102a81f4261be47b1c47add5693ac5c.png

再次修改 launchSettings.json 文件,通过环境变量设置 WebConfig:Name 的值,代码如下:

"IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Test",
        "WebConfig__Name": "itsvse env"
      }
    }

备注:环境变量修改 WebConfig:Name 的值,变量名称为:WebConfig__Name (中间用双下划线隔开

尝试重启项目,发现 WebConfig:Name 的值,已经被环境变量设置的值所覆盖,如下图:

176ede550deeb2b401600442598e4f05.png

尝试通过命令行的形式修改默认配置的值,启动命令如下:

dotnet run --WebConfig:Name="itsvse command"

如下图:

5e88de4a9f245c170b66f97f3bf9972b.png

用实践来测试配置键值的优先级,完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值