美文网首页Amazing .NETdotnet coredotNET
asp.net core重新加载应用配置

asp.net core重新加载应用配置

作者: 天天向上卡索 | 来源:发表于2019-04-19 19:23 被阅读9次

    asp.net core重新加载应用配置

    Intro

    我把配置放在了数据库或者是Redis里,配置需要修改的时候我要直接修改数据库,然后调用一个接口去重新加载应用配置,于是就尝试写一个运行时重新加载配置的接口。

    Configuration 重新加载实现

    重新加载配置的接口其实很简单,经过看 Configuration 的源码可以知道,如果想要重新加载应用配置,需要一个 IConfigurationRoot 对象,而 IConfigurationRoot 其实可以直接拿注入服务中的 IConfiguration 对象,服务中的 IConfiguration 对象也是实现了 IConfigurationRoot 接口的实例。后面我们一起看源码就更清晰了。

    来看实现重新加载配置的代码

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    
    namespace TestWebApplication.Controllers
    {
        [Route("api/[controller]")]
        public class ConfigurationsController : Controller
        {
            private readonly IConfigurationRoot _configuration;
    
            public ConfigurationsController(IConfiguration configuration)
            {
                _configuration = configuration as IConfigurationRoot;
            }
    
            [HttpGet]
            public IActionResult Get()
            {
                return Ok(new
                {
                    RootUser = _configuration.GetAppSetting("RootUser") // 这里 GetAppSetting 是一个自定义扩展方法,获取AppSettings 节点下的配置信息
                });
            }
    
            [HttpPut]
            public IActionResult Put()
            {
                _configuration.Reload();
                return Ok();
            }
        }
    }
    

    是不是很简单,下面我们来尝试一下,你可以参考这个示例项目

    因为默认的项目配置会监听 appsettings.json 文件是否修改,如果已修改就会重新reload,这里我新加一个文件,这里设置 reloadOnChangefalse,示例代码如下:

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration(configBuilder =>
                    {
                        configBuilder.AddJsonFile("abc.json", optional: true, reloadOnChange: false);
                    })
                    .UseStartup<Startup>();
    

    abc.json 的文件内容如下:

    {
      "AppSettings": {
        "TestNumber": 12,
        "RootUser": "WeihanLi"
      }
    }
    

    dotnet run 启动网站,然后在浏览器中访问 http://localhost:5000/api/configurations

    然后我们修改 abc.json 文件

    {
      "AppSettings": {
        "TestNumber": 12,
        "RootUser": "WeihanLi 123"
      }
    }
    

    修改保存之后刷新刚才的页面,可以看到还是刚才的内容,证明并没有重新加载配置,接下来尝试我们的重新加载配置方法

    使用 postman 或 fiddler 或其他你喜欢的工具发一个 PUT 请求到 http://localhost:5000/api/configurations,这里我使用 postman 调用 PUT 接口重新加载配置

    reload configuration

    返回 200 即接口调用成功,重新刷新刚才的页面就可以看到页面上的数据已经发生变化,这也就证明了我们重新加载配置的接口生效了。

    源码解析

    来看 ConfigurationBuilder 在 Build 的时候做了什么,ConfigurationBuilder 源码

    ConfigurationBuilder.Build()

    可以看到这里最后返回的是一个 IConfigurationRoot 对象,再来看 IConfigurationRoot 源码

    IConfigurationRoot

    可以看到 IConfigurationRoot 定义了一个 Reload 的方法,这个方法会从下面的 Providers 中重新加载配置,看到这里我们就知道可以通过 IConfigurationReload 方法来重新加载应用程序的配置了,然后我们来看 WebHost.CreateDefaultBuilder(args).Build() 做了什么
    https://github.com/aspnet/AspNetCore/blob/master/src/DefaultBuilder/src/WebHost.cs#L149

    WebHost

    这里我们可以看到为什么 appsettings.json 文件会自动 reload 配置,可以看到最后返回了一个 WebHostBuilder 对象

    看 Asp.Net core WebHostBuilder 对象的 Build 方法 https://github.com/aspnet/AspNetCore/blob/master/src/Hosting/Hosting/src/WebHostBuilder.cs#L135

    BuildCommonServices 可以看到这样一段代码 https://github.com/aspnet/AspNetCore/blob/master/src/Hosting/Hosting/src/WebHostBuilder.cs#L277

    image.png

    上面我们已经知道 ConfigurationBuilder Build 之后返回的是一个 IConfigurationRoot 对象,而这里注入是一个 IConfiguration 对象(IConfigurationRoot 实现 IConfiguration 接口),所以我们就可以从依赖注入中获取 IConfiguration 对象直接当作 IConfigurationRoot 来使用,这也就是为什么我们会直接获取一个 IConfiguration 对象直接 as IConfigurationRoot

    Memo

    到此就暂时结束了,希望你能有所收获~

    相关文章

      网友评论

        本文标题:asp.net core重新加载应用配置

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