ASP.NET Core中修改配置文件后自动加载新配置的方法详解
前言
在ASP.NETCore默认的应用程序模板中,配置文件的处理如下面的代码所示:
config.AddJsonFile( path:"appsettings.json", optional:true, reloadOnChange:true ); config.AddJsonFile( path:$"appsettings.{env.EnvironmentName}.json", optional:true, reloadOnChange:true );
appsettings.json和appsettings.{env.EnvironmentName}.json两个配置文件都是可选的,并且支持当文件被修改时能够重新加载。
可以在ASP.NETCore应用中利用这个特性,实现修改配置文件之后,不需要重启应用,自动加载修改过的配置文件,从而减少系统停机的时间。实现的步骤如下:
使用配置API进行注入
假设要在程序中注入这样一个配置类型:
publicclassWeatherOption{ publicstringCity{get;set;} publicintRefreshInterval{get;set;} }
在appsettings.json中添加的配置如下:
{ "weather":{ "city":"GuangZhou", "refreshInterval":120 } }
在Startup.cs的ConfigureServices方法中使用配置API进行注入,代码如下:
publicvoidConfigureServices(IServiceCollectionservices){ services.Configure(Configuration.GetSection("weather")); services.AddControllers(); }
这个步骤很关键,通过这个配置API可以把注入内容和配置所在的节点关联起来。如果有兴趣了解底层实现的话,可以继续查看这个OptionsConfigurationServiceCollectionExtensions.cs。
通过这种方式注册的内容,都是支持当配置文件被修改时,自动重新加载的。
在控制器(Controller)中加载修改过后的配置
控制器(Controller)在ASP.NETCore应用的依赖注入容器中注册的生命周期是Scoped,即每次请求都会创建新的控制器实例。这样只需要在控制器的构造函数中注入IOptionsSnapshot
[ApiController] [Route("[controller]")] publicclassWeatherForecastController:ControllerBase{ privateWeatherOptionoption; publicWeatherForecastController( IOptionsSnapshotoptions ){ this.option=options.Value; } //GET/weatherforcase/options [HttpGet("options")] publicActionResult GetOption(){ returnoptions; } }
当然,如果不希望在控制器中使用这个IOptionsSnapshot接口类型(会带来一些对现有代码重构和修改,还是有一定的风险的),可以在ConfigureServices中添加对WeatherOption的注入,代码如下:
publicvoidConfigureServices(IServiceCollectionservices){ services.Configure(Configuration.GetSection("weather")); //添加对WeatherOption的注入,生命周期为Scoped,这样每次请求都可以获取新的配置值。 services.AddScoped(serviceProvider=>{ varsnapshot=serviceProvider.GetService >(); returnsnapshot.Value; }); services.AddControllers(); }
这样在控制器中就不需要注入IOptionsSnapshot
[ApiController] [Route("[controller]")] publicclassWeatherForecastController:ControllerBase{ privateWeatherOptionoption; publicWeatherForecastController( WeatherOptionoption ){ this.option=option; } //GET/weatherforcase/options [HttpGet("options")] publicActionResultGetOption(){ returnoptions; } }
这样控制器就无需修改任何代码即可加载修改过后的新配置。
在中间件(Middleware)中加载修改过后的配置
中间件(Middleware)在ASP.NETCore应用的依赖注入容器中注册的生命周期是Singleton,即单例的,只有在当应用启动时,根据中间件创建处理连时创建一次全局实例,所以只能通过注入IOptionsMonitor
publicclassTestMiddleware{ privateRequestDelegatenext; privateWeatherOptionoption; publicTestMiddleware( RequestDelegatenext, IOptionsMonitormonitor ){ this.next=next; option=monitor.CurrentValue; //moniconfigchange monitor.OnChange(newValue=>{ option=newValue; }); } publicasyncTaskInvoke(HttpContextcontext){ awaitcontext.Response.WriteAsync(JsonSerializer.Serialize(option)); } }
当然,在中间件的TaskInvoke(HttpContextcontext)方法中,直接获取IOptionsSnapshot
publicasyncTaskInvoke(HttpContextcontext){ varsnapshot=context.RequestServices.GetService>(); awaitcontext.Response.WriteAsync(JsonSerializer.Serialize(snapshot.Value)); }
但是这么做的话,似乎就偏离了依赖注入的原则了,因此不推荐这种做法。
总结
到此这篇关于ASP.NETCore中修改配置文件后自动加载新配置的文章就介绍到这了,更多相关ASP.NETCore自动加载新配置内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。