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

    配置

    参考文件点击跳转

    配置来源

    • 命令行参数
    • 自定义提供程序
    • 目录文件
    • 环境变量
    • 内存中的.NET 对象
    • 文件

    默认配置

    • CreateDefaultBuilder方法提供有默认配置,在这个方法中会接收前缀为ASPNETCORE_的变量和命令行参数以及appsettings.json和appsettings.{Environment}.json等,可以通过下面的源码看到,注意配置文件的顺序
    • 一般顺序为
    1. 文件
    2. Azure
    3. 用户机密(生产中没有)
    4. 环境变量
    5. 命令行参数

    命令行参数可以更新替换相关的程序设置,与前面提到的顺序有关,详细见下面的约定

     public static IWebHostBuilder CreateDefaultBuilder(string[] args)
            {
                var builder = new WebHostBuilder();
    
                if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
                {
                    builder.UseContentRoot(Directory.GetCurrentDirectory());
                }
                if (args != null)
                {
                    builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
                }
    
                builder.UseKestrel((builderContext, options) =>
                    {
                        options.Configure(builderContext.Configuration.GetSection("Kestrel"));
                    })
                    .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())
                        {
                            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) =>
                    {
                        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                        logging.AddConsole();
                        logging.AddDebug();
                        logging.AddEventSourceLogger();
                    })
                    .ConfigureServices((hostingContext, services) =>
                    {
                        // Fallback
                        services.PostConfigure<HostFilteringOptions>(options =>
                        {
                            if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
                            {
                                // "AllowedHosts": "localhost;127.0.0.1;[::1]"
                                var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                                // Fall back to "*" to disable.
                                options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
                            }
                        });
                        // Change notification
                        services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
                            new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));
    
                        services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
                    })
                    .UseIIS()
                    .UseIISIntegration()
                    .UseDefaultServiceProvider((context, options) =>
                    {
                        options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
                    });
    
                return builder;
            }
    

    相关约定

    • 键不区分大小写,但是linux好像区分,所以最好还是有区分的好
    • 同键值会被覆盖,以最后的为准
    • 环境变量中,冒号分隔不适应用所有的平台,但是双下划线支持所有的平台
    • Azure中用两个破折号,国内有阿里的比较多
    • ConfigurationBinder支持配置到对象的转换,有Bind和Get<>的两种方式,注意区分,建议用Get
    • 值是字符串且NULL不能出现在配置文件中也不能绑定到相应的对象中去

    参数提供程序

    主机通过ConfigureAppConfiguration指定应用配置程序

    命令行参数提供程序

    配置
    • 其实CreateDefaultBuider已经支持了,但是如果需要应用程序配置并能实现覆盖的功能就需要在CnfigureAppConfiguration中添加并且在最后添加AddCommandLine如下:
    //一种写法
    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    // Call other providers here and call AddCommandLine last.
                    config.AddCommandLine(args);
                })
                .UseStartup<Startup>();
    //另一种写法
    var config = new ConfigurationBuilder()
        // Call additional providers here as needed.
        // Call AddCommandLine last to allow arguments to override other configuration.
        .AddCommandLine(args)
        .Build();
    
    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>();
    
    使用
    • 命令行后有两种赋值方式,等号和空格(键前必顺有--或/),不要混合使用(知道的多不是让你乱用的,你的明白)
    • 等号赋值 值可以为null
    dotnet run CommandLineKey1=value1 --CommandLineKey2=value2 /CommandLineKey3=value3
    dotnet run --CommandLineKey1 value1 /CommandLineKey2 value2
    dotnet run CommandLineKey1= CommandLineKey2=value2
    
    • 交换映射
      就是给命令行的键值改名,以-开头的必顺要交换,再加上默认提供程序没有注入的地方,如果硬传将造成格式异常,所以可以通过AddCommandLine在ConfigureAppConfiguration中进行传递
    public static readonly Dictionary<string, string> _switchMappings = 
            new Dictionary<string, string>
            {
                { "-CLKey1", "CommandLineKey1" },
                { "-CLKey2", "CommandLineKey2" }
            };
      WebHost.CreateDefaultBuilder()
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddCommandLine(args, _switchMappings);
                })
                .UseStartup<Startup>();
    

    环境变量提供程序

    注意:分隔无法适应所有的平台,__可以,由加载顺序可以知道环境变量是可以替换appsettings文件中的配置,注意默认的环境变量前缀是ASPNETCORE_所以为了区分自己添加的不要用这个前缀了,前缀尽量见名知义,一个结果 就是能自解

    配置

    与命令行一样在ConfigureAppConfiguration中添加并声明前缀,如下:

     WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    // Call additional providers here as needed.
                    // Call AddEnvironmentVariables last if you need to allow environment
                    // variables to override values from other providers.
                    config.AddEnvironmentVariables(prefix: "PREFIX_");
                })
                .UseStartup<Startup>();
    //二种写法
    var config = new ConfigurationBuilder()
        .AddEnvironmentVariables()
        .Build();
    
    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>();
    
    使用

    就是配置系统级的环境变量,不同的系统不太一样,windows可以在属性->环境变境中找到,linux可以命令行配置也可以直接改文件

    文件配置提供程序(重点,重点,使用比较多)

    首先明白不论何种文件,一定要能根据路径找到,所以我们一定要通过SetBasePath设置基路径,然后再是不同的文件

    INI文件

    配置

    与前面的一样也是在ConfigureAppConfiguration中添加

     WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddIniFile("config.ini", optional: true, reloadOnChange: true);
                })
                .UseStartup<Startup>();
    //二种
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddIniFile("config.ini", optional: true, reloadOnChange: true)
        .Build();
    
    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>();
    

    JSON文件

    配置
      WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddJsonFile("config.json", optional: true, reloadOnChange: true);
                })
                .UseStartup<Startup>();
    //二种
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("config.json", optional: true, reloadOnChange: true)
        .Build();
    
    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>();
    

    XML文件

    配置
     WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddXmlFile("config.xml", optional: true, reloadOnChange: true);
                })
                .UseStartup<Startup>();
    //另一种写法(二种)
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddXmlFile("config.xml", optional: true, reloadOnChange: true)
        .Build();
    
    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>();
    

    Key-pre-file配置提供程序

    使用目录的文件作为配置,键是文件名,值是包含在文件的内容。路径必顺是绝对路径。双下划线字符 (__) 用作文件名中的配置键分隔符。 例如,文件名 Logging__LogLevel__System 生成配置键 Logging:LogLevel:System

    配置
     WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    var path = Path.Combine(Directory.GetCurrentDirectory(), "path/to/files");
                    config.AddKeyPerFile(directoryPath: path, optional: true);
                })
                .UseStartup<Startup>();
    //二种
    var path = Path.Combine(Directory.GetCurrentDirectory(), "path/to/files");
    var config = new ConfigurationBuilder()
        .AddKeyPerFile(directoryPath: path, optional: true)
        .Build();
    
    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>();
    

    内存配置提供程序

    就是内存中的对象(字典对象之流)结构为IEnumerable<KeyValuePair<String,String>>

    配置
    public static readonly Dictionary<string, string> _dict = 
            new Dictionary<string, string>
            {
                {"MemoryCollectionKey1", "value1"},
                {"MemoryCollectionKey2", "value2"}
            };
    WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddInMemoryCollection(_dict);
                })
                .UseStartup<Startup>();
    //二种
    var dict = new Dictionary<string, string>
        {
            {"MemoryCollectionKey1", "value1"},
            {"MemoryCollectionKey2", "value2"}
        };
    
    var config = new ConfigurationBuilder()
        .AddInMemoryCollection(dict)
        .Build();
    
    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>();  
    

    获取配置内容

    • GetSection 获取指定子节键提取值
    • GetChildren 获取节点的值
    • Bind 把字符串构造为POCO对象
    • Get 绑定并返回指定类型 Get 比使用 Bind 更方便

    绑定是按约定提供的。 不需要自定义配置提供程序实现数组绑定。

    可以在代码中读到相应的值

    
                var configEntryFilter = new string[] { "ASPNETCORE_", "urls", "Logging", "ENVIRONMENT", "contentRoot", "AllowedHosts", "applicationName", "CommandLine" };
                var config = cfg.AsEnumerable();
                FilteredConfiguration = config.Where(
                   kvp => config.Any(
                       i => configEntryFilter.Any(prefix => kvp.Key.StartsWith(prefix))));
                var starship = new Starship();
                cfg.GetSection("starship").Bind(starship);
                Starship = starship;
                TvShow = cfg.GetSection("tvshow").Get<TvShow>();
                ArrayExample = cfg.GetSection("array").Get<ArrayExample>();
                JsonArrayExample = cfg.GetSection("json_array").Get<JsonArrayExample>();
                Customer customer = cfg.GetSection("customer").Get<Customer>();
                var value1 = cfg.GetValue<object>("name", "read error");  
    

    自定义配置提供程序

    该示例应用演示了如何使用实体框架 (EF) 创建从数据库读取配置键值对的基本配置提供程序。
    倒着分析(正分析看官文)

    • 我们要添加一个配置到ConfigurationBuilder中(可以用扩展 AddEFConfiguration)
    • 要扩展我们要有配置内容类来作为载体EFConfigurationContext
    • 我们要用对应的内容解析类来提供解析 EFConfigurationProvider
    • 最后我们要有解析出来对应的对象来进行绑定 EFConfigurationValue

    -最后我们要注入到ConfigureServices和Configure中这样就可以在指定的作用域内使用了
    详见我抄官网上的git源码点击跳转,同样官网上的源码也是可以运行的。

  • 相关阅读:
    毕业设计进度5(2月5日)
    毕业设计进度4(2月4日)
    Intellij IDEA 安装Scala插件 + 创建Scala项目
    中国HBase技术社区第一届Meetup资料大合集
    【大会PPT+直播回顾】HBaseCon亚洲2018峰会
    Java 中的锁原理、锁优化、CAS、AQS 详解!
    Reactor 反应堆设计模式
    IO模型
    浅析Reactor设计模式
    将IDEA工程代码提交到Github
  • 原文地址:https://www.cnblogs.com/ants_double/p/10511863.html
Copyright © 2011-2022 走看看