首页 > 技术文章 > 13 | 配置绑定:使用强类型对象承载配置数据

wwwk 2022-02-08 23:53 原文

要点

  • 支持将配置值绑定到已有对象
  • 支持将配置值绑定到私有属性上
    • 默认情况下我们只能绑定public

示例


继续沿用我们上一次创建的控制台应用程序,
新添加一个包Microsoft.Extensions.Configuration.Binder
image.png
首先我们新建一个类,来作为我们接受配置的实例

class Config
{
    public string Key1 { get; set; }
    public string Key2 { get; set; }
    public bool Key3 { get; set; }
    public int Key4 { get; set; }
}

然后利用新添加的包,这个包的作用就是让我们能够很方便的把配置绑定到我们的强类型上面去。

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using System;

namespace ConfigurationFileDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder();
            var root = builder.AddJsonFile("appsettings.json").Build();
            var config = new Config
            {
                Key1 = "Config_Key1",
                Key2 = "Config_Key2",
                Key3 = true,
                Key4 = 10086
            };
            root.Bind(config);
            Console.WriteLine($"Key1 : {config.Key1}");
            Console.WriteLine($"Key2 : {config.Key2}");
            Console.WriteLine($"Key3 : {config.Key3}");
            Console.WriteLine($"Key4 : {config.Key4}");
        }
    }
    class Config
    {
        public string Key1 { get; set; }
        public string Key2 { get; set; }
        public bool Key3 { get; set; }
        public int Key4 { get; set; }
    }
}

利用root.Bind(config);将其绑定到Config上。在此之前我们给这个config赋值。
执行代码:image.png 配置文件:image.png
可以看到,输出的值和我们之前定义的并不一样,说明这是从配置里读取出来的。


通常来说,我们的配置文件不会这么简单,一般都是嵌套的格式,我们将配置文件修改为以下形式

{
  "Key1": "Value1",
  "Key2": "Value2",
  "Key3": false,
  "Key4": 10,
  "Other": {
    "Other_Key1": "Other_Value1",
    "Other_Key2": "Other_Value2",
    "Key4": 10010
  }
}

在这种情形下面,我们就需要把我们的section绑定给我们的config对象

class Program
{
    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder();
        var root = builder.AddJsonFile("appsettings.json").Build();
        var config = new Config
        {
            Key1 = "Config_Key1",
            Key2 = "Config_Key2",
            Key3 = true,
            Key4 = 10086
        };
        root.Bind(config);
        root.GetSection("Other").Bind(config);
        Console.WriteLine($"Key1 : {config.Key1}");
        Console.WriteLine($"Key2 : {config.Key2}");
        Console.WriteLine($"Key3 : {config.Key3}");
        Console.WriteLine($"Key4 : {config.Key4}");
    }
}

我们在root.Bind(config)的下面,添加一行代码root.GetSection("Other").Bind(config),然后运行输出:
image.png
可以发现,从配置中读取值,然后第二行代码会读取到了Other的值,把之前的Key4的值也会覆盖。
一般情况下,我们会把配置的某些值设置为私有的,防止在别处修改。
Config类修改为如下

class Config
{
    public string Key1 { get; set; }
    public string Key2 { get; set; }
    public bool Key3 { get; set; }
    public int Key4 { get; private set; } = 10086;
}

然后我们再去执行代码:
image.png
发现私有的属性并没有从配置中自动绑定上。
这时,我们需要利用Bind方法的参数,设置Options,将Bind方法修改为
root.Bind(config, configureOptions => { configureOptions.BindNonPublicProperties = true; });
BindNonPublicProperties默认是false
输出:image.png
然后把OtherBind方法也修改
root.GetSection("Other").Bind(config, configureOptions => { configureOptions.BindNonPublicProperties = true; });
输出:image.png

推荐阅读