京东6.18大促主会场领京享红包更优惠

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 9604|回复: 0

浅析.netcore中的Configuration具体使用

[复制链接]

22

主题

0

回帖

10

积分

新手上路

积分
10
发表于 2022-1-13 08:34:59 | 显示全部楼层 |阅读模式 来自 中国
目录
$ m& T. Z; F8 G/ C3 s: l, \8 `6 k& _; P/ B- F( X6 d+ Z; g% C

    4 {5 a3 K- Y! c' T7 C: G8 j
  • 添加其他配置文件0 t* y" C& s" l
  • 源码解读:$ m* {; i9 M! ^3 j
  • 读取层级配置项  X' o0 U4 C# k; `- U( J; q) t  {
  • 选项模式获取配置项. G! t7 w0 L, V4 x$ X4 J7 _
  • 命名选项的使用' a8 }. O4 h: N, Z( N5 S3 q' ]
不管是.net还是.netcore项目,我们都少不了要读取配置文件,在.net中项目,配置一般就存放在web.config中,但是在.netcore中我们新建的项目根本就看不到web.config,取而代之的是appsetting.json。4 A2 J! A! V& p3 h! H; ?3 g1 O
新建一个webapi项目,可以在startup中看到一个IConfiguration,通过框架自带的IOC使用构造函数进行实例化,在IConfiguration中我们发现直接就可以读取到appsetting.json中的配置项了,如果在控制器中需要读取配置,也是直接通过构造& v/ ~8 `' [% @- O) o
函数就可以实例化IConfiguration对象进行配置的读取。下面我们试一下运行的效果,在appsetting.json添加一个配置项,在action中可以进行访问。
) \4 Z& e: ]5 f2 D: f: F
; }9 u  b1 w' H& `4 V+ p8 Z
. E3 I/ J9 X4 D+ r
添加其他配置文件+ K) `3 p6 }5 k( p. g' B

3 i- w* e9 `* O4 r那我们的配置项是不是只能写在appsetting.json中呢?当然不是,下面我们看看如何添加其他的文件到配置项中,根据官网教程,我们可以使用ConfigureAppConfiguration实现。
+ t7 a' u# _7 `0 s首先我们在项目的根目录新建一个config.json,然后在其中随意添加几个配置,然后在program.cs中添加高亮显示的部分,这样很简单的就将我们新增的json文件中的配置加进来了,然后在程序中就可以使用IConfiguration进行访问config.json中的配置项了。
  1. public class Program{    public static void Main(string[] args)    {        CreateHostBuilder(args).Build().Run();    }    public static IHostBuilder CreateHostBuilder(string[] args) =>        Host.CreateDefaultBuilder(args)            .ConfigureAppConfiguration(configure => {                               configure.AddJsonFile("config.json");  //无法热修改            })            .ConfigureWebHostDefaults(webBuilder =>            {                webBuilder.UseStartup();            });}
复制代码
但是这个无法在配置项修改后读取到最新的数据,我们可以调用重载方法configure.AddJsonFile("config.json",true,reloadOnChange:true)实现热更新。
9 T2 P1 p4 w5 O2 i除了添加json文件外,我们还可以使用AddXmlFile添加xml文件,使用AddInMemoryCollection添加内存配置
  1. public static IHostBuilder CreateHostBuilder(string[] args) =>    Host.CreateDefaultBuilder(args)        .ConfigureAppConfiguration((context,configure) => {            Dictionary memoryConfig = new Dictionary();            memoryConfig.Add("memoryKey1", "m1");            memoryConfig.Add("memoryKey2", "m2");                configure.AddInMemoryCollection(memoryConfig);            })        .ConfigureWebHostDefaults(webBuilder =>        {            webBuilder.UseStartup();        });
复制代码
源码解读:( j0 Y% p0 N7 @3 W

/ W$ ]0 ?* U3 Q! e3 n4 _在自动生成的项目中,我们没有配置过如何获取配置文件,那.netcore框架是怎么知道要appsetting.json配置文件的呢?我们通过查看源码我们就可以明白其中的道理。
  1. Host.CreateDefaultBuilder(args)        .ConfigureWebHostDefaults(webBuilder =>    {        webBuilder.UseStartup();    });//CreateDefaultBuilder源码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);        }    });        ....    return builder;}
复制代码
怎么样?是不是很有意思,在源码中我们看到在Program中构建host的时候就会调用ConfigureAppConfiguration对应用进行配置,会读取appsetting.json文件,并且会根据环境变量加载不同环境的appsetting,同时还可以看到应用不仅添加了
# S! F# \% {6 q- ~- h, P% Q/ ~appsetting的配置,而且添加了从环境变量、命令行传入参数的支持,对于AddUserSecrets支持读取用户机密文件中的配置,这个在存储用户机密配置的时候会用到。
# Q. c4 L% B& U1 m+ {8 i那为什么我们可以通过再次调用ConfigureAppConfiguration去追加配置信息,而不是覆盖呢?我们同样可以在源码里面找到答案。
  1. public static void Main(string[] args){    CreateHostBuilder(args).Build().Run();}//以下为部分源码private List _configureAppConfigActions = new List();private IConfiguration _appConfiguration;public IHostBuilder ConfigureAppConfiguration(Action configureDelegate){    _configureAppConfigActions.Add(configureDelegate ?? throw new ArgumentNullException(nameof(configureDelegate)));    return this;}public IHost Build(){    ...    BuildAppConfiguration();    ...}private void BuildAppConfiguration(){    var configBuilder = new ConfigurationBuilder()        .SetBasePath(_hostingEnvironment.ContentRootPath)        .AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true);    foreach (var buildAction in _configureAppConfigActions)    {        buildAction(_hostBuilderContext, configBuilder);    }    _appConfiguration = configBuilder.Build();    _hostBuilderContext.Configuration = _appConfiguration;}
复制代码
框架声明了一个List,我们每次调用ConfigureAppConfiguration都是往这个集合中添加元素,等到Main函数调用Build的时候会触发ConfigurationBuilder,将集合中的所有元素进行循环追加
+ X6 f' g0 B* n" o( ]- ?到ConfigurationBuilder,最后就形成了我们使用的IConfiguration,这样一看对于.netcore中IConfiguration是怎么来的就很清楚了。
) A( P1 j! y3 B% n5 n; E" W- o7 r+ Z+ z2 i- f
读取层级配置项+ x% L0 }" e# B
( }5 c. |* P* \% I
如果需要读取配置文件中某个层级的配置应该怎么做呢?也很简单,使用IConfiguration["key:childKey..."]
4 w. N1 A4 n$ W. P, ?. @  D  v2 X比如有这样一段配置:
  1. "config_key2": {    "config_key2_1": "config_key2_1",    "config_key2_2": "config_key2_2"  }
复制代码
可以使用IConfiguration["config_key2:config_key2_1"]来获取到config_key2_1的配置项,如果config_key2_1下还有子配置项childkey,依然可以继续使用:childkey来获取
0 i+ c  `: t0 O  F4 `$ v( U- c) Z9 _
选项模式获取配置项
, P$ r% O! B( `3 _9 }- T# B& e* I# H1 D( v2 k# O
选项模式使用类来提供对相关配置节的强类型访问,将配置文件中的配置项转化为POCO模型,可为开发人员编写代码提供更好的便利和易读性/ N% F; h9 R6 g) ~& M, Z
我们添加这样一段配置:
  1. "Student": {    "Sno": "SNO",    "Sname": "SNAME",    "Sage": 18,    "ID": "001"  }
复制代码
接下来我们定义一个Student的Model类
  1. public class Student{    private string _id;    public const string Name = "Student";    private string ID { get; set; }    public string Sno { get; set; }    public string Sname { get; set; }    public int Sage { get; set; }}
复制代码
可以使用多种方式来进行绑定:
1 v- E2 V7 y  H7 m9 Q8 d' g1、使用Bind方式绑定
  1. Student student = new Student();_configuration.GetSection(Student.Name).Bind(student);
复制代码
2、使用Get方式绑定
  1. var student1 = _configuration.GetSection(Student.Name).Get(binderOptions=> {  binderOptions.BindNonPublicProperties = true;});
复制代码
Get方式和Bind方式都支持添加一个Action的重载,通过这个我们配置绑定时的一些配置,比如非公共属性是否绑定(默认是不绑定的),但是Get比BInd使用稍微方便一些,如果需要绑定集合也是一样的道理,将Student0 |3 ~1 v8 C: A* G' z
替换成List。
" S( w4 Y1 @3 F) _5 r3、全局方式绑定
: r5 M" Y. _1 F5 |前两种方式只能在局部生效,要想做一次配置绑定,任何地方都生效可用,我们可以使用全局绑定的方式,全局绑定在Startup.cs中定义
  1. services.Configure(Configuration.GetSection(Student.Name));
复制代码
此方式会使用选项模式进行配置绑定,并且会注入到IOC中,在需要使用的地方可以在构造函数中进行实例化
  1. private readonly ILogger _logger;private readonly IConfiguration _configuration;private readonly Student _student;public WeatherForecastController(ILogger logger, IConfiguration configuration, IOptions student){    _logger = logger;    _configuration = configuration;    _student = student.Value;}
复制代码
命名选项的使用# Q( y; s3 `& z3 g" X3 Y* Z

, D% y' ]/ V) A3 p& E8 m: T对于不同的配置节,包含的配置项一样时,我们在使用选项绑定的时候无需定义和注入两个类,可以在绑定时指定名称,比如下面的配置:
  1. "Root": {  "child1": {    "child_1": "child1_1",    "child_2": "child1_2"  },  "child2": {    "child_1": "child2_1",    "child_2": "child2_2"  }}public class Root{  public string child_1{get;set;}  public string child_2{get;set;}}services.Configure("Child1",Configuration.GetSection("Root:child1"));services.Configure("Child2", Configuration.GetSection("Root:child2"));private readonly ILogger _logger;private readonly IConfiguration _configuration;private readonly Student _student;private readonly Root _child1;private readonly Root _child2;public WeatherForecastController(ILogger logger, IConfiguration configuration, IOptions student,IOptionsSnapshot root){    _logger = logger;    _configuration = configuration;    _student = student.Value;    _child1 = root.Get("Child1");    _child2 = root.Get("Child2");}
复制代码
到此这篇关于浅析.netcore中的Configuration具体使用的文章就介绍到这了,更多相关.net core Configuration内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!* I  M$ O- l7 n
7 M$ E, I/ C. F1 ]+ f
来源:http://www.jb51.net/article/232944.htm1 [" y* Q5 s& |7 d5 g
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

帖子地址: 

梦想之都-俊月星空 优酷自频道欢迎您 http://i.youku.com/zhaojun917
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|梦想之都-俊月星空 ( 粤ICP备18056059号 )|网站地图

GMT+8, 2026-4-28 05:15 , Processed in 0.036672 second(s), 24 queries .

Powered by Mxzdjyxk! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表