zoukankan      html  css  js  c++  java
  • ASP.NET Core 中的配置 【上】

    此为系列文章,对MSDN ASP.NET Core 的官方文档进行系统学习与翻译。其中或许会添加本人对 ASP.NET Core 的浅显理解。 

        ASP.NET Core中的应用程序配置是基于配置提供器建立的键值对的。配置提供器从各种配置源中读取配置数据到键值对中。配置源包含如下:

    • Azure密钥库
    • Azure应用程序配置
    • 命令行参数
    • 自定义提供器(装载的或者新建的)
    • 字典文件
    • 环境变量
    • 内存中.NET对象
    • 设置文件

           通用配置提供器场景的配置Pakages隐式的包含在框架中。

           接下来以及在示例中的代码使用了Microsoft.Extensions.Configuration 命名空间。

    using Microsoft.Extensions.Configuration;

           选项模式是本章描述的配置概念的一个扩展。选项模式使用类来代表一组相关的配置。更多信息,请参考Options pattern in ASP.NET Core

           View or download sample code (how to download)

    宿主与App 配置

           在app被配置以及启动之前,一个宿主会被配置和加载。宿主负责app的启动以及生命周期管理。app以及宿主都会使用本章描述的配置提供器进行配置。宿主配置键值对会包含在app配置中。关于在宿主被建立时,配置提供器如何使用以及配置源如何影响宿主配置的更多信息,请参考ASP.NET Core fundamentals

    其他配置

          本章主题仅仅适用于app.configration。运行以及寄宿ASP.NET Core apps的其他方面将使用其他配置文件进行配置,其不包含在本章主题之中。

          关于从早期版本的ASP.NET 中迁移配置文件的更多信息,请参考:Migrate from ASP.NET to ASP.NET Core

    默认配置

          基于ASP.NET Core dotnet new 模板创建的web app在建立一个宿主的时候会调用CreateDefaultBuilderCreateDefaultBuilder 按照如下顺序为app 提供默认的配置:

          以下内容适用于使用了Generic Host 的app。当使用Web Host时,关于默认配置的更多信息,请参考ASP.NET Core 2.2 version of this topic

    安全

          对于安全敏感的配置数据采取以下实践:

    • 绝对不要将密码以及其他敏感数据存储在配置提供器代码中,或者在纯文本配置文件中。
    • 在开发环境以及测试环境中,不要使用生产环境的密钥。
    • 将密钥在项目工程之外指定,这样它们便不会被自动提交给源码库。

           更多信息,请参考如下主题:

            Azure密钥库 为ASP.NET Core app安全的存储app密钥。更多信息,请参考Azure Key Vault Configuration Provider in ASP.NET Core

    层次化的配置数据

            配置API可用维护层次化的配置数据,器通过使用配置键中的分号(;)来将层次化的数据扁平化。

            在如下的Json文件中,四个键值存在于两部分组成的结构化的等级制度中。

    {
      "section0": {
        "key0": "value",
        "key1": "value"
      },
      "section1": {
        "key0": "value",
        "key1": "value"
      }
    }

          当文件被读入到配置中,会创建唯一的键值来维护原始的来自于配置源的层次化数据结构。我们使用一个冒号来将部分以及键值进行扁平化处理,以维护原始的数据结构:

    • section0:key0
    • section0:key1
    • section1:key0
    • section1:key1

         GetSection 以及 GetChildren 方法可用来分离开各个部分以及它们的子节点。这些方法在GetSection, GetChildren, and Exists 中会有描述。

    惯例

           源以及提供器

           在app启动时,配置源被按照器配置提供器被指定的顺序被读取。

           实现了更新检测的提供器当底层的设置被更新时可以重加载配置。举个例子,文件配置提供器(本章后续会有描述)以及Azure Key Vault Configuration Provider 都实现了更改探测。

          IConfiguration 在app 的DI容器中是可用的。IConfiguration 可以被注入到一个Razor页面的 PageModel 中 或者是 MVC的Controller 中,从而为这个类获取配置数据。

          在如下的示例中,_config 字段被用来访问配置值:

    public class IndexModel : PageModel
    {
        private readonly IConfiguration _config;
    
        public IndexModel(IConfiguration config)
        {
            _config = config;
        }
    }
    public class HomeController : Controller
    {
        private readonly IConfiguration _config;
    
        public HomeController(IConfiguration config)
        {
            _config = config;
        }
    }

           配置提供器不能使用DI,因为当它们被宿主建立的时候DI还是不可用的。

           键

           配置键值采取了如下约定:

    • 键是大小写不敏感的。举个例子,ConnectionString和connectionstring 被当作相等的键。
    • 如果一个相同键的值被相同或者不同的配置提供器所设置,那么最后一个设置的值将会被使用。
    • 层次化的键值
      • 在配置API之内,冒号分隔符在所有的平台都能工作。
      • 在环境变量中,冒号分隔符可能不能在所有的平台下都能工作。但双下划线(__)会被所有的平台支持,并自动转换为一个冒号。
      • 在Azure密钥库中,层次化的键值使用 (--) 作为一个分隔符。当密钥被加载到app的配置中的时候,需要些代码来使用冒号将(-)替换掉。
    • ConfigurationBinder 支持将数组绑定到对象,数组绑定在Bind an array to a class 章节会有相应的介绍。

         值

         配置值采取如下的约定:

    • 值都是字符串。
    • 空值不能被存储在配置中或者绑定给对象。

    提供器

          下列表格展示了ASP.NET Core app中可用的配置提供器:

                                      

    ProviderProvides configuration from…
    Azure Key Vault Configuration Provider (Security topics) Azure Key Vault
    Azure App Configuration Provider (Azure documentation) Azure App Configuration
    Command-line Configuration Provider Command-line parameters
    Custom configuration provider Custom source
    Environment Variables Configuration Provider Environment variables
    File Configuration Provider Files (INI, JSON, XML)
    Key-per-file Configuration Provider Directory files
    Memory Configuration Provider In-memory collections
    User secrets (Secret Manager) (Security topics) File in the user profile directory

          在app启动时,配置源按照其配置提供器指定的顺序被读取。本章描述的配置提供器是按照字符顺序,而不是代码安排它们的顺序来描述的。在代码中对配置提供器进行排序以匹配app所需要的底层配置源的优先级。

          一个典型的配置提供器序列是:

    1. 文件(appsettings.json, appsettings.{Environment}.json, 其中{Environment} 是应用程序的当前寄宿环境)
    2. Azure密钥库
    3. 用户密钥(Secret Manager)(仅针对开发环境)
    4. 环境变量
    5. 命令行参数

          一个通用的实践是将命令行配置提供器放置在一系列提供器的最后,以允许命令行参数重载被其他提供器设置的配置。

          当一个新的宿主被使用CreateDefaultBuilder来初始化的时候,上面的提供器序列会被使用。更多 信息,请参考Default configuration 章节。

    使用ConfigureHostConfiguration来配置宿主构造器

           为了配置宿主构造器,可以调用ConfigureHostConfiguration 并提供配置数据。ConfigureHostConfiguration 用来初始化IHostEnvironment 以供后续构造进程使用。ConfigureHostConfiguration 可以被调用多次以产生额外的结果。

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureHostConfiguration(config =>
            {
                var dict = new Dictionary<string, string>
                {
                    {"MemoryCollectionKey1", "value1"},
                    {"MemoryCollectionKey2", "value2"}
                };
    
                config.AddInMemoryCollection(dict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

     ConfigureAppConfiguration

          当构造宿主时候可以调用ConfigureAppConfiguration 以指定除了被CreateDefaultBuilder自动添加的之外其他的app的配置提供器。

    public class Program
    {
        public static Dictionary<string, string> arrayDict = 
            new Dictionary<string, string>
            {
                {"array:entries:0", "value0"},
                {"array:entries:1", "value1"},
                {"array:entries:2", "value2"},
                {"array:entries:4", "value4"},
                {"array:entries:5", "value5"}
            };
    
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddInMemoryCollection(arrayDict);
                    config.AddJsonFile(
                        "json_array.json", optional: false, reloadOnChange: false);
                    config.AddJsonFile(
                        "starship.json", optional: false, reloadOnChange: false);
                    config.AddXmlFile(
                        "tvshow.xml", optional: false, reloadOnChange: false);
                    config.AddEFConfiguration(
                        options => options.UseInMemoryDatabase("InMemoryDb"));
                    config.AddCommandLine(args);
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

           使用命令行参数重载之前的配置

           为了提供可被命令行参数重载的配置,可以在最后调用AddCommandLine:

    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        // Call other providers here
        config.AddCommandLine(args);
    })

          移除被CreateDefaultBuilder 添加的提供器

          为了移除被CreateDefaultBuilder 添加的提供器,可以首先在IConfigurationBuilder.Sources 上调用Clear

    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        config.Sources.Clear();
        // Add providers here
    })

          在app启动时消费配置

          在ConfigureAppConfiguration中提供给app的配置在app的启动阶段是可用的,包括Startup.ConfigureServices方法。更多信息,请参考Access configuration during startup 章节。

    命令行配置提供器

           CommandLineConfigurationProvider 在运行时从命令行参数键值对加载配置数据。

           为了激活命令行配置,可以在ConfigurationBuilder的实例上调用AddCommandLine 扩展方法。

           当调用CreateDefaultBuilder 方法时,AddCommandLine 方法会被自动调用。更多信息,请参考Default configuration 章节。

           CreateDefaultBuilder 也会加载:

          CreateDefaultBuilder 最后会添加命令行配置提供器。运行时传递的命令行参数会重载被其他提供器设置的配置。

          当宿主被构造时,CreateDefaultBuilder便会行动起来。因此,被CreateDefaultBuilder激活的命令行配置可以影响宿主如何被配置。

          对于基于ASP.NET Core模板的app来说,AddCommandLine 已经被CreateDefaultBuilder 所调用。为了添加额外的配置提供器,并且维护使用命令行参数重载配置的能力,可以在ConfigureAppConfiguration中调用额外的提供器并最后调用AddCommandLine

    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        // Call other providers here
        config.AddCommandLine(args);
    })

          示例

          示例app使用静态约定方法CreateDefaultBuilder来构建宿主,其包含了一个对AddCommandLine的调用。

    1. 在工程目录中打开一个命令提示符。
    2. dotnet run命令提供命令行参数:dotnet run CommandLineKey=CommandLineValue
    3. app运行之后,打开浏览器:http://localhost:5000
    4. 可以观察到,输出包含了提供给dotnet run命令的键值对。

          参数

          参数值必须跟着一个=,或者当值跟随一个空格时,键值必须有一个前缀(--/),如果使用一个=号时,那么值不是必须的(比如 CommandLineKey=)。

                                    

    Key prefixExample
    No prefix CommandLineKey1=value1
    Two dashes (--) --CommandLineKey2=value2, --CommandLineKey2 value2
    Forward slash (/) /CommandLineKey3=value3, /CommandLineKey3 value3

          但是在一个命令行内,最好不要混合使用两种形式的参数。示例命令:

    dotnet run CommandLineKey1=value1 --CommandLineKey2=value2 /CommandLineKey3=value3
    dotnet run --CommandLineKey1 value1 /CommandLineKey2 value2
    dotnet run CommandLineKey1= CommandLineKey2=value2

         交换映射

         交换映射运行键名称替换逻辑。当使用ConfigurationBuilder 手动构建一个配置时,为AddCommandLine 方法提供一个交互替换的字典。

         当交互映射字典被使用时,字典便会检查以寻找与命令行参数提供的键匹配的键。如果命令行键在字典中被 找到,那么字典的值便会回传给app配置以设置键值对。对于任何具有前缀(-)的命令行键,都会需要一个交互映射。

         交互映射字典键的规则:

    • 必须以一个 - 或者 两个 -- 开始。
    • 交互映射字典不能包含重复的键。

         创建一个交互映射字典。在下列示例中,两个交互映射被创建:

    public static readonly Dictionary<string, string> _switchMappings = 
        new Dictionary<string, string>
        {
            { "-CLKey1", "CommandLineKey1" },
            { "-CLKey2", "CommandLineKey2" }
        };

          当宿主被构造时,使用交互映射字典为参数来调用AddCommandLine:

    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        config.AddCommandLine(args, _switchMappings);
    })

          对于使用交互映射的app来说,对CreateDefaultBuilder 的调用不应该传递参数。CreateDefaultBuilder方法的AddCommandLine 调用不包含映射的交互。并且没有方法来给CreateDefaultBuilder传递交互映射字典。我们的解决方案并不是给CreateDefaultBuilder 传递参数,而是允许ConfigurationBuilder方法的AddCommandLine 方法来处理参数以及交互映射字典。

          在交互映射字典被创建之后,其包含了下表所示的数据:

    KeyValue
    -CLKey1 CommandLineKey1
    -CLKey2 CommandLineKey2

          在app启动时,如果使用了交互映射字典,配置便会在字典提供的键值上接受配置值:

    dotnet run -CLKey1=value1 -CLKey2=value2

          运行上面的命令后,配置会包含下表所示的配置值:

    Key     Value
    CommandLineKey1     value1
    CommandLineKey2     value2
  • 相关阅读:
    Java设计模式-----装饰模式
    Java并发包中Lock的实现原理
    ThreadLocal,静态变量,实例变量,局部变量的线程安全
    ThreadLocal类详解
    SQL之LEFT JOIN,EIGHT JOIN,INSERT JOIN的区别
    Wireshark 、HTTPWatch、Fiddler的介绍
    TCP/IP、HTTP、Socket的区别
    我希望你并不幸福
    Autoregressive Convolutional Neural Networks for Asynchronous Time Series
    DRL Lecture1:Policy Gradient
  • 原文地址:https://www.cnblogs.com/qianxingmu/p/12504285.html
Copyright © 2011-2022 走看看