Net Core 的配置模式以及热重载配置 Net Core 的配置模式以及热重载配置

Net Core 的配置模式以及热重载配置

1. 前言

在提倡微服务及 Serverless 愈来愈普及的当下,传统 .Net 应用的配置模式每每依赖于一个名为 web.config 的 XML 文件,在可扩展性和可读性与时代脱节了。固然,我不会怂恿一会儿把全部应用迁移到 .Net Core 上,本文将在尽可能不引入 .Net Core 开发模式的前提下,得到最大的利益。javascript

在开始以前,咱们仍是先说说 .Net Core 的配置模式有何优点以及最少的依赖。css

1.1 .Net Core 配置模式的优点

  • 支持多种格式,如 Json、ini、Yaml、系统环境变量等
  • 再也不依赖于 web.config ,可同时使用多种配置格式
  • 支持热重载配置,修改配置能够不用重启应用

1.2 最少依赖

nuget install Microsoft.Extensions.Configuration nuget install Microsoft.Extensions.Configuration.Binder nuget install Castle.Windsor (其余 IOC 框架都可)

若是你安装的是最新的包,可能会遇到 Microsoft.Extensions.Configuration 系列 Nuget 包没法安装的问题,这主要取决当前应用的 .Net 版本,请参考下图,安装对应的版本(目前不支持 .Net 4.5 如下的应用)。
版本兼容状况html

因为本人喜欢可读性高的 Json 文件,因此还安装 Microsoft.Extensions.Configuration.Json 的 Nuget 包。java

2. 示例教程

本文在 Abp 2.1.3 的基础上实现 .Net Core 的配置模式以及热重载配置,更详细的过程可参照我在 Github 上的 提交历史 。git

2.1 加载配置

.Net Core 配置模式的核心是一个名为 IConfigurationRoot 的接口对象,须要在应用入口中加载各类配置格式后建立一个 IConfigurationRoot 的实例,在传统的 .Net Web 应用中是在 Global.asax.cs 中赋值。github

// ConfigurationExtenion.AppConfiguration 为一个静态的 IConfigurationRoot 实例。 ConfigurationExtenion.AppConfiguration = new ConfigurationBuilder() .AddJsonFile("appsetting.json", optional: false, reloadOnChange: true) .AddJsonFile("appsetting01.json", optional: true, reloadOnChange: false) .Build();

简单地解释一下,咱们须要(在根目录中) 有一个名为 "appsetting.json" 的 Json 文件,被修改的同时会重载 ConfigurationExtenion.AppConfiguration 。与之相反的 "appsetting01.json" 则容许不存在,即便存在,被修改时不会重载配置。web

2.2 读取配置节点

加载配置后,咱们须要把配置读取出来,在 IConfigurationRoot 中全部配置的信息都是存在于一个个节点中,咱们能够根据节点名称来获取对应的类型对象。redis

/// <summary> /// 获取节点配置 /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="config"></param> /// <param name="sectionName"></param> /// <returns></returns> internal static TService GetSectionObject<TService>(IConfigurationRoot config, String sectionName) { var section = config.GetSection(sectionName); if (section == null) { throw new ArgumentException($" {sectionName} 未绑定,没法获取到配置节点信息!"); } return section.Get<TService>(); }

假设咱们有一个这样的 "appsetting.json" 文件:mongodb

{
    "RedisConfiguration": { "InstanceDbId": 14, "InstanceRedisConnectionString": "127.0.0.1" }, "MongoDbConfiguration": { "ConnectionString": "mongodb://127.0.0.1:27017/?connectTimeoutMS=300000", "DatatabaseName": "local" } }

若是咱们要获取 MongoDbConfiguration 下的 ConnectionString 的值,那么咱们能够这样获取:json

var connectionString= GetSectionObject<String>(ConfigurationExtenion.AppConfiguration,"MongoDbConfiguration:ConnectionString");

2.3 设计配置类

在传统的 .Net 应用程序中,咱们每每会使用一个静态变量去存放配置信息。而在有 IOC 的状况下,更好的方法是设计一个类来存放配置,如上面的 Json 文件咱们能够设计以下两个类(在 Visual Studio 选择性黏贴 Json 会自动生成对象):

public class RedisConfiguration { public int InstanceDbId { get; set; } public string InstanceRedisConnectionString { get; set; } } public class MongodbConfiguration { public string ConnectionString { get; set; } public string DatatabaseName { get; set; } }

2.4 注册配置

为了实现热重载配置,而不是一层不变的值,咱们在 IOC 中获取配置类时,须要使用工厂方法获取。在 Windsor 中能够这么作:

/// <summary> /// 注册方法 /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="ioc"></param> /// <param name="factoryMethod"></param> private static void Register<TService>(IIocManager ioc, Func<TService> factoryMethod) where TService : class { ioc.IocContainer .Register( Component.For<TService>() .UsingFactoryMethod(factoryMethod) .LifestyleTransient() //这里的生命周期是瞬时的,单例不能够吗? ); }

结合前面的获取配置节点,咱们能够把两个静态方法组合起来创造一个新的静态方法,更方便咱们使用。

/// <summary> /// 注册配置 /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="ioc"></param> /// <param name="config"></param> /// <param name="sectionName"></param> internal static void InitConfigService<TService>(IIocManager ioc, IConfigurationRoot config, String sectionName) where TService : class { Register(ioc, () => { var service = GetSectionObject<TService>(config, sectionName); return service; }); }

对于前面两个配置类,咱们能够这样注入:

ConfigurationExtenion.InitConfigService<RedisConfiguration>(IocManager,ConfigurationExtenion.AppConfiguration, "RedisConfiguration"); ConfigurationExtenion.InitConfigService<MongodbConfiguration>(IocManager, ConfigurationExtenion.AppConfiguration, "MongoDbConfiguration");

2.5 获取配置

我在这里新增一个控制器方法获取 RedisConfiguration 对象,该方法使用属性注入获取指定的配置类,并返回给页面。

public String GetRedisConfig() { var redisConfig = IocManager.Instance.Resolve<RedisConfiguration>(); return redisConfig.ToJsonString(); }

能够看到页面显示的与 Json 文件中结构一模一:
结果

2.6 热重载配置

与 .Net Core 不同,在 .Net 4.X 的 Web 应用中只是稍微修改下 Json 文件都会让整个应用重启(修改 web.config 一样会重启),因此我将 "appsetting.json" 重命名为 "appsetting.conf" ,在运行时修改某些值,并从新访问控制器,能够看到对应的值变了。

效果

须要注意 IIS 的安全配置,Json 或者 ini 也许能直接经过 HTTP 获取!

3. 结语

经过简单的使用 .Net Core 配置模式,咱们能够感觉到其强大魅力,若是你对 .Net Core 更多的了解,以及感觉二者的对比,能够对照我以前写过的一篇文章。对于热重载配置,.Net Core 中更可能是使使用IOptionsSnapshot,而为了尽可能少地引入 .Net Core 的特性,在这里只是简单地用了 IOC 的特性。固然,在不使用任何 IOC 的状况下(若是你惧怕引入 IOC ),定义一个 IConfigurationRoot 的全局静态实例,也不失为一个折中的方案。

相关文章
相关标签/搜索