.net core学习(四).NET的全新的配置文件机制

勇哥注:

 传统的web.config和app.config的缺点是必须存在于本地,并且使用上也不方便。

.NET中为了兼容,仍然可以使用web.config和ConfigurationManager类,但是不推荐。



 .NET中的配置系统支持丰富的配置源,包括文件(json,xml,ini等),注册表,环境变量,

命令行,Azure Key Vault(云端配置服务器)等,还可以配置自定义配置源。可以跟踪配置的改变,多个配置文件时可以按照优先级覆盖。

这些变化使用得.NET的配置文件功能更符合现代程序的需求,比如面向云的配置文件的需求。


(一)最经典的是本地json文件方式


1。 创建一个json文件,比如config.json,设置“如果较新则复制”。

2。 NuGet安装Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.Json


Microsoft.Extensions.Configuration  是配置框架的包,因为它支持许多种配置方式

Microsoft.Extensions.Configuration.Json是它的一种方式,因此需要装两个包


使用nuget的程序包管理器控制台进行安装:

image.png


准备好json文件,内容如下:

{
  "Age": "32",
  "Name": "刘备",
  "Proxy": {"Address": "wuhan"}
}

json文件可以选择WEB下的模板,如下图。

其实你也可以选择一个纯文本文件,改扩展名为json也可以。

image.png


注意此json文件属性要选择”如果较新则复制“,否则它不会被复制到bin目录,会引发运行时出错。

image.png


(1.1) 基本方式

这一种方式跟我们读app.config或者web.config方式相似。

    ConfigurationBuilder cbuilder = new ConfigurationBuilder();
    cbuilder.AddJsonFile("myconfig.json", optional: true, reloadOnChange: true);
    IConfigurationRoot configroot = cbuilder.Build();
    var name = configroot["name"];
    var add = configroot.GetSection("Proxy:Address").Value; //要读的值是一个对象时
    Console.WriteLine($"name={name},Address={add}");
    Console.ReadKey();


结果:

name=刘备,address=wuhan


(1.2) 用对象方式读取配置


请先安装下面的包:

Microsoft.Extensions.Configuration.Binder


代码:

 static void Main(string[] args)
 {
   ConfigurationBuilder cbuilder = new ConfigurationBuilder();
    cbuilder.AddJsonFile("myconfig.json", optional: true, reloadOnChange: true);
    IConfigurationRoot configroot = cbuilder.Build();

   MyData? data= configroot.Get<MyData>();
   Console.WriteLine($"name={data.Name},Age={data.Age},Address={data.Proxy.address}");
   Console.ReadKey();
 }
        
 public class MyData
  {
      public int Age { get; set; }
      public string? Name { get; set; }

      public Proxy? proxy { get; set; }
  }

  public class Proxy
  {
      public string? Address { get; set; }
  }

结果:

name=刘备,Age=32,Address=wuhan



(三)使用选项方式读取,和DI结合,也更好利用reloadonchange机制。
(推荐)


需要安装 :

Microsoft.Extensions.Options

Microsoft.Extensions.Configuration.Binder

Microsoft.Extensions.Configuration

Microsoft.Extensions.Configuration.Json

Microsoft.Extensions.DependencyInjection     //这个是IoC框架


以使用nuget控制台指令,示例如下:

PM> install-package Microsoft.Extensions.Options



读取配置的时候,DI要声明IOptions<T>  IOptionsMonitor<T> IOptionsSnapshot<T>等类型

IOptions<T>不会读取到新的值;和IOptionsMonitor相比,

IOptionsMonitor  会立刻读到新的值

IOptionsSnapshot会在同一个范围内(比如asp.net core一个请求中)保持一致。


建议用IOptionsSnapshot。


1。在读取配置的地方,用IOptionsSnapshot<T>注入。
不要在构造函数里直接读取IOptionsSnapshot.Value, 而是到用到的地方再读取,
否则就无法更新变化。

2。 如下配置

Sservices.AddOptions().Configure<DbSettings>(e=> config.GetSection("DB").Bind(e))

.Configure<SmtpSettings>(e=>config.GetSection("Smtp").Bind(e));

services.AddTransient<Demo>();  //不能用Singleton


json文件内容:

{
  "Age": "32",
  "Name": "刘备",
  "Proxy": { "Address": "wuhan" }
}


源码:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Xml.Linq;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddScoped<ConfigController>();
            services.AddScoped<ConfigController2>();

            ConfigurationBuilder cbuilder = new ConfigurationBuilder();
            cbuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);
            IConfigurationRoot configroot = cbuilder.Build();

            //让DI把 MyData对象绑定到根结点上去
            services.AddOptions()
                .Configure<MyData>(e => configroot.Bind(e))
                .Configure<Proxy>(e => configroot.GetSection("Address").Bind(e));

            services.BuildServiceProvider();

            using (var sp = services.BuildServiceProvider())
            {
                while (true)
                {
                    using (var scope = sp.CreateScope())
                    {
                        var c = scope.ServiceProvider.GetRequiredService<ConfigController>();
                        c.Test();

                        var d = scope.ServiceProvider.GetRequiredService<ConfigController2>();
                        d.Test();
                    }
                    Console.WriteLine("按任意键继续....");
                    Console.ReadKey();
                }

            }

        }
    }

    public class MyData
    {
        public int Age { get; set; }
        public string? Name { get; set; }

        public Proxy? proxy { get; set; }
    }

    public class Proxy
    {
        public string? Address { get; set; }
    }
}

控制器:

DI还是通过构造函数方法 ,注入IOptionsSnapshot<MyData>

using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class ConfigController
    {
        public readonly IOptionsSnapshot<MyData> optConfig;

        public ConfigController(IOptionsSnapshot<MyData> optConfig)
        {
            //这里一定要返回IOptionsSnapshot对象,而不是取它的值(就是MyData)
            //如果取它的value的话,你就失去了灵活性,当配置文件修改时,就得不到更新的内容了。
            //this.optConfig = optConfig.Value;  

            this.optConfig = optConfig;
        }

        public void Test()
        {
            Console.WriteLine(optConfig.Value.Age);
            Console.WriteLine("********");
            Console.WriteLine(optConfig.Value.Age);
        }

    }

    public class ConfigController2
    {
        public readonly IOptionsSnapshot<Proxy> optConfig;

        public ConfigController2(IOptionsSnapshot<Proxy> optConfig)
        {
            this.optConfig = optConfig;
        }

        public void Test()
        {
            Console.WriteLine(optConfig.Value.Address);
        }

    }
}



修改一下json文件的Age为22,然后接任意键,可以看到现在值更新了。

image.png


源码下载:

链接:https://pan.baidu.com/s/1ssZLHX9mqLVhGeBiVmZ0cg

提取码:2nr9 

--来自百度网盘超级会员勇哥V6的分享



--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2024-05-27 15:15:56 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864