美文网首页dotNET.NetcoreC#
.NET Core 自定义配置源

.NET Core 自定义配置源

作者: BeckJin | 来源:发表于2019-11-16 14:33 被阅读0次

    正如大家所知,在 .NET Core 中配置文件改成了 appsettings.json,表面上和 .NET Framework 的 web.configapp.config 好像没有太大的区别,只是一种是 json ,一种是 xml,但其实 .NET Core 的配置体系是一种全新的设计,灵活且具扩展性。这里主要介绍一下在 .NET Core 的配置体系下如何扩展自定义配置源,配置源其实就是配置信息存放的载体,最常用的就是文件类型。

    .NET Core 配置体系

    在进行自定义配置源介绍前,我们需要先了解一下 .NET Core 中的配置体系。 .NET Core 的配置体系中主要包含 ConfigurationProviderConfigurationSourceConfigurationBuilderConfiguration 几大核心对象。

    ConfigurationProvider

    实现 IConfigurationProvider 接口,配置源真正提供者,主要提供配置信息的加载与刷新。

    ConfigurationSource

    实现 IConfigurationSource 接口,提供对应的 ConfigurationProvider 具体实例。

    ConfigurationBuilder

    实现 IConfigurationBuilder 接口,负责将 ConfigurationSource 添加到配置源集合,再根据配置源集合构建出 ConfigurationRoot 对象,实现 IConfigurationRoot 接口。

    Configuration

    实现 IConfiguration 接口,Configuration 对象在逻辑上体现出树形化层次结构,配置信息均以键/值对的方式提供使用。

    注 :IConfigurationRootIConfigurationSection 均继承于 IConfigurationIConfigurationRoot 表示配置的根节点,IConfigurationSection 则表示配置的非根节点

    所以他们之间的关系就是 ConfigurationProvider 实现配置提供,然后通过 ConfigurationSource 构造配置源实例,接着通过 ConfigurationBuilder 将配置源实例 ConfigurationSource 添加到配置源集合中并构造出 ConfigurationRoot,最终以 Configuration 对象提供给程序使用。

    relation

    默认情况下,Configuration 对象的 Providers 属性包含如下 Provider

    providers
    1. ChainedConfigurationProvider:应用程序本身相关配置信息,如:applicationName、contentRoot;
    2. JsonConfigurationProvider:appsettings.json 和 appsettings.Development.json 中的配置信息;
    3. EnvironmentVariablesConfigurationProvider:环境变量的配置信息;
    4. CommandLineConfigurationProvider:命令行输入的配置信息;

    这些类型的 Provider 在 .NET Core Web 项目中默认会自动加载,不需要手动配置,当然预置的 Provider 并不止这几种。

    自定义配置源

    前面提到 .NET Core 的配置体系是具有扩展性的,所以我们可以实现自定义的配置源,比如基于配置中心(如:etcd、apollo、consul 等)的实现,下面将模拟从配置中心获取,先了解整体实现方式,后面也会介绍我们在实际项目中基于 etcd 的实现方案。

    创建 ConfigurationProvider

    自定义 Provider 需要继承 ConfigurationProvider,然后重写 Load 方法,设置 Data 属性。

    public class CustomConfigurationProvider : ConfigurationProvider
    {
      public override void Load()
      {
        // 模拟从远程配置中心获取配置信息 
        using var httpClient = new HttpClient
        {
          BaseAddress = new Uri("http://localhost:5000")
        };
    
        var response = httpClient.GetStringAsync("/api/configs")
          .ConfigureAwait(false)
          .GetAwaiter()
          .GetResult();
    
        if (!string.IsNullOrEmpty(response))
        {
          Data = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
        }
      }
    }
    

    http://localhost:5000/api/configs 接口返回的 json 字符串,如下:

    {"name":"beck","company":"mingdao"}
    

    创建 ConfigurationSource

    实现 IConfigurationSource 接口,在 Build 方法中返回 CustomConfigurationProvider 实例。

    public class CustomConfigurationSource : IConfigurationSource
    {
      public IConfigurationProvider Build(IConfigurationBuilder builder)
      {
        return new CustomConfigurationProvider();
      }
    }
    

    加入 ConfigurationBuilder 配置源列表

    添加 IConfigurationBuilder 扩展方法 AddCustom,将 CustomConfigurationSource 加入配置源集合中。

    public static class CustomConfigurationExtensions
    {
      public static IConfigurationBuilder AddCustom(this IConfigurationBuilder builder)
      {
        return builder.Add(new CustomConfigurationSource());
      }
    }
    

    启动入口添加 AddCustom

    Program.cs 中的 ConfigureAppConfiguration 引用自定义配置源:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
          webBuilder.ConfigureAppConfiguration((context, configBuiler) =>
          {
            configBuiler.AddCustom();
          });
          webBuilder.UseStartup<Startup>();
        });
    

    测试效果

    再次查看 Configuration 对象的 Providers 属性,发现已包含 CustomConfigurationProvider

    customConfigurationProvider

    然后可通过 Configuration 对象获取对应 key 的内容:

    [HttpGet]
    public IEnumerable<string> Get()
    {
      return new string[] { _configuration["name"], _configuration["company"] };
    }
    
    result

    总结

    以上完成了一个简单的自定义配置源,实际情况会比这复杂些。如果关注过 JsonConfigurationProvider 的配置加载参数,有一个 reloadOnChange 参数用来设置当配置文件有变化时是否重新加载,如果 reloadOnChange 设置为 true,当配置文件变化时不需要重启服务就可以生效,很多时候我们是需要 Provider 具有这个功能的,在接下来介绍的 EtcdConfigurationProvider 中会实现,实现源码 已在 Github 可供参考。

    相关文章

      网友评论

        本文标题:.NET Core 自定义配置源

        本文链接:https://www.haomeiwen.com/subject/khreictx.html