从零开始:如何在 .NET Core 中优雅地读取和管理配置文件

在.net中的配置文件系统支持丰富的配置源,包括文件(json、xml、ini等)、注册表、环境变量、命令行、Azure Key Vault等,还可以配置自定义配置源并跟踪配置的改变,然后按照优先级进行覆盖,总之对文件的配置有很多方法,这里我们就举几个最常用的例子来讲解。

目录

config配置管理

选项方式读取

配置提供方式

自定义配置


config配置管理

配置json文件:是目前最常用的配置文件格式,在.net中也有许多针对json文件格式进行处理的配置,这里我们可以直接在.net core项目中添加一个json文件,然后里面写一些配置信息,如下:

{
  "name": "test-app",
  "age": "20",
  "proxy": {"address": "aaa"}
} 

写好config.json配置文件之后,我们需要右键其属性然后设置一下复制到最新目录的情况:

然后我们借助NuGet安装两个包,如下一个是对config配置的包,一个是对json操作的包:

然后我们执行如下语句,通过ConfigurationBuilder加载一个json配置文件,从配置中读取简单的键值对(例如 "name")以及嵌套的配置项(例如 "proxy:address"),输出读取到的配置信息:

namespace Program
{
    class Program
    {
        static void Main(string[] args)
        {
            ConfigurationBuilder configBuilder = new ConfigurationBuilder();
            configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);
            IConfiguration configRoot = configBuilder.Build();
            string name = configRoot["name"];
            Console.WriteLine($"name = {name}");
            string address = configRoot.GetSection("proxy:address").Value;
            Console.WriteLine($"address = {address}");
            Console.ReadKey();
        }
    }
}

得到的结果如下所示:

绑定读取配置:当然我们还可以绑定一个类去自动完成配置的读取,首先我们先借助NuGet安装如下一个包:

然后我们定义一个类来映射config中的proxy配置,然后通过Get方式拿到相应数据展示:

namespace Program
{
    class Program
    {
        static void Main(string[] args)
        {
            ConfigurationBuilder configBuilder = new ConfigurationBuilder();
            configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);
            IConfiguration configRoot = configBuilder.Build();
            Proxy proxy = configRoot.GetSection("proxy").Get<Proxy>();
            Console.WriteLine($"Proxy: address={proxy.Address} port={proxy.Port}");
            Console.ReadKey();
        }
    }
    class Proxy
    {
        public string Address { get; set; }
        public string Port { get; set; }
    }
}

得到的结果如下所示: 

当然我们还可以直接通过Get拿到config中的数据,通过定义相关的类然后设置对应的类型即可:

选项方式读取

在读取文件中推荐使用选项方式进行读取,和DI结合方式比较好且能更好的利用reloadonchange机制,这里除了上文我们需要安装的三个包之外,这里我们还是需求安装一下下面这个包:

读取配置的时候,DI要声明IOptions<T>、IOptionsMonitor<T>、IOptionsSnapshot<T>等类型,因为IOptions<T>不会读取到新的值,和IOptionsMonitor<T>相比IOptionsSnapshot会在同一个范围内(.net core一个请求中)保持一致,因此建议使用IOptionsSnapshot<T>类型。

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

在TestController中使用依赖注入模式来管理和访问配置,通过IOptionsSnapshot<Config>获取配置文件中的值(例如 name 和 age):

namespace test
{
    class TestController
    {
        private readonly IOptionsSnapshot<Config> optConfig;
        public TestController(IOptionsSnapshot<Config> optConfig)
        {
            this.optConfig = optConfig;
        }
        public void Test()
        {
            Console.WriteLine(optConfig.Value.name);
            Console.WriteLine(optConfig.Value.age);
        }
    }
}

接下来通过通过IOptions接口来读取配置文件并将其注入到类中,

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

            ConfigurationBuilder configBuilder = new ConfigurationBuilder();
            configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);
            IConfiguration configRoot = configBuilder.Build();

            services.AddOptions().Configure<Config>(e => configRoot.Bind(e));
            using(var sp = services.BuildServiceProvider())
            {
                var test = sp.GetRequiredService<TestController>();
                test.Test();
            }

            Console.ReadKey();
        }
    }
    class Config
    {
        public string name { get; set; }
        public string age { get; set; }
        public Proxy Proxy { get; set; }
    }
    class Proxy
    {
        public string Address { get; set; }
        public string Port { get; set; }
    }
}

如下执行通过使用ServiceProvider获取TestController实例,TestController在构造时自动注入配置,最后TestController调用了Test()方法输出配置文件中的name、age详细信息:

配置提供方式

读取调试参数:配置文件除了上面讲解的读取config等配置文件的方式外,框架还支持从命令行参数、环境变量等地方读取, 借助NuGet安装如下的包进行使用:

安装完包之后,我们将之前加载json文件的格式修改为命令行的形式,如下:

然后我们右键我们的项目选择属性,然后找到调试的按钮,输入相关的参数信息即可,对于环境变量或命令行等简单的键值对结构,如果想要进行复杂结构的配置,需要进行扁平化处理,对于配置的名字需要采用“层级配置”,例如:a:b:c 赋值的话这样配置 a:b:c:0,例如:

name=zhangsan;age=18;proxy:address=aaa;proxy:port=80;

proxy:ids:0=3;proxy:ids:1=5;

输入完成之后我们的项目会自动生成一个配置文件,然后我们运行项目之后就会打印该文件内容:

读取环境变量:如果想读取环境变量中的数据的话,可以借助NuGet安装如下的包

然后我们在环境变量中配置如下的数据,VS调试时为了避免修改系统环境变量,可以直接在VS中设置环境变量的方法:

然后我们就可以我们在使用环境变量的函数获取当前环境变量的数据,该函数是有参数和没有参数两种情况的,无参数版本会把程序相关的所有环境变量都加载进来,由于有可能和系统中已有的环境变量冲突,因此这边可以建议使用有prefix参数进行配置读取的,读取配置的时候prefix参数会被忽略:

当然.net core还支持其他配置源,例如ini、xml等格式的配置源,还支持在运行或调试时加载不同的json文件,而且还内置了第三方支持中心化配置服务器,例如Azure、阿里云等,具体使用可以查询相关文档,这里不再赘述。

自定义配置

.net core中不建议使用.net framework里的web.config,不过仍继续提供ConfigurationManager,不过官方没有支持通过新的Configuration框架读取方式,这里我们建议自行编写一个自定义配置提供者,实际使用意义不大,主要还是了解读取配置的方法。具体步骤如下:

编写ConfigurationProvider类实际读取配置

开发一个直接或间接实现IConfigurationProvider接口的类xxxConfigurationProvider,一般继承自ConfigurationProvider,如果是从文件读取是可以继承自FileConfigurationProvider,重写Load方法把扁平化数据设置到Data属性即可。

ConfigurationSource在Build中返回ConfigurationProvider对象

开发一个实现IConfigurationSource接口的类xxxConfigurationSource,如果是从文件读取可以继承自FileConfigurationSource,在Build方法中返回上面的ConfigurationProvider对象。

ConfigurationSource对象加入IConfigurationBuilder

使用configurationBuilder.Add(new ConfigurationSource())即可,为了简化使用一般还提供一个IConfigurationBuilder的扩展方法。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亦世凡华、

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值