C#配置系统

读取JSON文件

NuGet两个包:Microsoft.Extensions.Configuration,Mircosoft.Extensions.Configuration.Json

{
  "name": "yjw",
  "age": 18,
  "proxy": {"address": "aa"}
}

需要注意的是,上述json文件,需要设置为”如果较新则复制“,确保在exe同目录下复制该配置文件。

ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("config.json", true, true);
            IConfigurationRoot configRoot=configurationBuilder.Build();
            string name = configRoot["name"];
            var age = configRoot["age"];
            Console.WriteLine(name);
            string address = configRoot.GetSection("proxy:address").Value;
            Console.WriteLine(address);

output:

yjw
aa

除了以上的操作,还可以帮定一个类,自动完成配置的读取,NuGet安装:Microsoft.Extensions.Configuration.Binder

{
  "name": "yjw",
  "age": 18,
  "proxy": {"address": "aa","port": "80"}
}

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;

namespace DITest
{
    internal class Program1
    {
        static void Main()
        {
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("config.json", true, true);
            IConfigurationRoot configRoot=configurationBuilder.Build();
            //GetSection返回IConfigurationSection类型,再使用其Get泛型方法,直接可以得到Proxy类
            Proxy proxy =configRoot.GetSection("proxy").Get<Proxy>();
            Console.WriteLine($"{proxy.address},{proxy.port}");
            Console.ReadKey();
        }
    }
    /// <summary>
    /// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
    /// </summary>
    class Proxy
    {
        public string address { get; set; }
        public int port { get; set; }
    }
}

output:

aa,80

当然也可以直接用一个类来bind根节点

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;

namespace DITest
{
    internal class Program1
    {
        static void Main()
        {
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("config.json", true, true);
            IConfigurationRoot configRoot=configurationBuilder.Build();
            Config config = configRoot.Get<Config>();
            Console.WriteLine($"{config.Proxy.address},{config.Proxy.port},{config.Name},{config.Age}");
            Console.ReadKey();
        }
    }

    class Config
    {
        public string Name { get; set; }
        public string Age { get; set; }
        public Proxy Proxy { get; set; }
    }


    /// <summary>
    /// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
    /// </summary>
    class Proxy
    {
        public string address { get; set; }
        public int port { get; set; }
    }
}

output:

aa,80,yjw,18

选取方式读取

推荐使用选项方式读取,和DI结合更好,且更好利用”reloadOnChange“机制。

NuGet安装:Microsoft.Extensions.Options,Microsoft.Extensions.Configuration.Binder

读取配置的时候,DI要声明IOptions<T>IOptionsMonitor<T>IOptionsSnapshot<T>等类型。IOptions<T>不会读取到新的值;和IOptionsMonitor相比,IOptionSnapshot<T>会在同一个范围内保持一致,因此,建议使用IOptionSnapshot

Testontrollers.cs:


using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace DITest
{
    internal class TestControllers
    {
        private readonly IOptionsSnapshot<Config> optConfig;//通过IOptinosSnapshot,将配置类注入

        public TestControllers(IOptionsSnapshot<Config> optConfig)//通过IOptinosSnapshot,将配置类注入
        {
            this.optConfig = optConfig;
        }
        public void Test()
        {
            Console.WriteLine(optConfig.Value.Name);//通过optConfig.Value获取Config实例
            Console.WriteLine(optConfig.Value.Age);
        }
    }
}


using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace DITest
{
    internal class Program1
    {
        static void Main()
        {
            ServiceCollection sc = new ServiceCollection();
            sc.AddScoped<TestControllers>();//注册TestControllers
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("config.json", true, true);
            IConfigurationRoot configRoot=configurationBuilder.Build();
            sc.AddOptions().Configure<Config>(e=>configRoot.Bind(e));//注册包裹在IOptionSnapshot中的Config
            using(var sp = sc.BuildServiceProvider())
            {
                var c = sp.GetRequiredService<TestControllers>();
                c.Test();
            }
            Console.ReadKey();
        }
    }

    class Config
    {
        public string Name { get; set; }
        public string Age { get; set; }
        public Proxy Proxy { get; set; }
    }


    /// <summary>
    /// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
    /// </summary>
    class Proxy
    {
        public string address { get; set; }
        public int port { get; set; }
    }
}

output:

yjw
18

如果只绑定proxy:

/// <summary>
    /// 只读proxy
    /// </summary>
    class TestControllers2
    {
        private readonly IOptionsSnapshot<Proxy> optProxy;
        public TestControllers2(IOptionsSnapshot<Proxy> optProxy)
        {
            this.optProxy = optProxy;
        }  
        public void Test()
        {
            Console.WriteLine(optProxy.Value.address);
            Console.WriteLine(optProxy.Value.port);
        }
    }
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace DITest
{
    internal class Program1
    {
        static void Main()
        {
            ServiceCollection sc = new ServiceCollection();
            sc.AddScoped<TestControllers>();//注册TestControllers
            sc.AddScoped<TestControllers2>();//注册TestControllers2
            ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
            configurationBuilder.AddJsonFile("config.json", true, true);
            IConfigurationRoot configRoot=configurationBuilder.Build();
            sc.AddOptions().Configure<Config>(e=>configRoot.Bind(e)).
                Configure<Proxy>(e=>configRoot.GetSection("proxy").Bind(e));//绑定proxy
            using(var sp = sc.BuildServiceProvider())
            {
                var c = sp.GetRequiredService<TestControllers2>();
                c.Test();
            }
            Console.ReadKey();
        }
    }

    class Config
    {
        public string Name { get; set; }
        public string Age { get; set; }
        public Proxy Proxy { get; set; }
    }


    /// <summary>
    /// 具备与json中的proxy里面的key相同的属性名称【首字母大小写都可以】
    /// </summary>
    class Proxy
    {
        public string address { get; set; }
        public int port { get; set; }
    }
}

output:

aa
80

命令行方式配置

需要NuGet安装Microsoft.Extensions.Configuration.CommandLine

configBuilder.AddCommandLine(args)

参数支持多种格式,比如server=127.0.0.1,--server=127.0.0.1,--server 127.0.0.1/server=127.0.0.1,/server 127.0.0.1

在cmd模式下:xxx.exe name=johnyang age=18

就可以得到该参数.

在VS中,可以在调试属性中,直接写入args

扁平化配置

对于环境变量,命令行等简单的键值对结构,如果想要进行复杂结构的配置,需要进行“扁平化处理”,对于配置的名字需要采用“层级配置”。

比如,json中的

{
    "a":{"b":"c"},
"d":{e:[3,5,7]}
}

在cmd中配置为:

a:b:=c d:e:0=3  d:e:1=5  d:e:2=7
posted @ 2022-09-04 23:46  JohnYang819  阅读(421)  评论(0编辑  收藏  举报