.NET 5 修改配置不重启自动生效

  • .NET Core,.NET 5 默认配置都是只加载一次,修改配置时都需要重启才能生效,如何能修改即时生效呢

设置配置文件实时生效

1.配置

  1. public static IHostBuilder CreateHostBuilder(string[] args) =>
  2. Host.CreateDefaultBuilder(args)
  3. .ConfigureAppConfiguration((context, config) =>
  4. {
  5. //重点代码
  6. config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
  7. })
  8. .ConfigureWebHostDefaults(webBuilder =>
  9. {
  10. webBuilder.UseStartup<Startup>();
  11. });

2.验证

  • appsettings.json文件内容如下
  1. {
  2. "TestSetting": "123",
  3. "AppOptions": {
  4. "UserName": "zhangsan"
  5. }
  6. }
  • 代码
  1. public class HomeController : Controller
  2. {
  3. private readonly ILogger<HomeController> _logger;
  4. private readonly IConfiguration _configuration;
  5. //
  6. public HomeController(ILogger<HomeController> logger, IConfiguration configuration)
  7. {
  8. _logger = logger;
  9. _configuration = configuration;
  10. }
  11. public IActionResult Index()
  12. {
  13. string Name = _configuration["TestSetting"];
  14. string Name2 = _configuration["AppOptions:UserName"];
  15. ViewBag.Name = Name;
  16. ViewBag.Name2 = Name2;
  17. return View();
  18. }
  19. }

IOptions方式实时生效

新建AppOptions.cs类

  1. /// <summary>
  2. /// 配置文件
  3. /// </summary>
  4. public class AppOptions
  5. {
  6. public string UserName { get; set; }
  7. }

在Startup.cs处把配置加到Options

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddControllersWithViews();
  4. services.Configure<AppOptions>(Configuration.GetSection("AppOptions"));
  5. }

使用

  1. public class HomeController : Controller
  2. {
  3. private readonly ILogger<HomeController> _logger;
  4. private readonly IConfiguration _configuration;
  5. private IOptionsMonitor<AppOptions> _options;
  6. public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IOptionsMonitor<AppOptions> appOptions)
  7. {
  8. _logger = logger;
  9. _configuration = configuration;
  10. _options = appOptions;
  11. }
  12. public IActionResult Index()
  13. {
  14. string Name = _configuration["TestSetting"];
  15. string Name2 = _options.CurrentValue.UserName;
  16. ViewBag.Name = Name;
  17. ViewBag.Name2 = Name2;
  18. return View();
  19. }
  20. }

IOptions有三种方式

  • IOptions<T> //站点启动后,获取到的值永远不变
  • IOptionsMonitor<T> //站点启动后,如果配置文件有变化会发布事件 (加载配置时,reloadOnChange:true 必须为true)
  • IOptionsSnapshot<T> //站点启动后,每次获取到的值都是配置文件里的最新值 (加载配置时,reloadOnChange:true 必须为true)

  • 注意:

IOptionsMonitor<T>IOptionsSnapshot<T> 的最大区别是前者可以被其他的Singleton Services使用而后者不可以, 因为前者被注册为Singleton 而后者是被注册为Scoped,也就是说文件被修改了前者会立即Reload,而后者是在每个请求才被Reload。

  • 例:
  1. public class HomeController : Controller
  2. {
  3. private readonly ILogger<HomeController> _logger;
  4. private UserService _userService;
  5. public HomeController(ILogger<HomeController> logger, UserService userService)
  6. {
  7. _userService = userService;
  8. }
  9. public IActionResult Index()
  10. {
  11. string Name2 = _userService.GetName();
  12. ViewBag.Name2 = Name2;
  13. return View();
  14. }
  15. }
  16. public class UserService
  17. {
  18. private IOptionsMonitor<AppOptions> _options;
  19. public UserService(IOptionsMonitor<AppOptions> appOptions)
  20. {
  21. _options = appOptions;
  22. }
  23. public string GetName()
  24. {
  25. var Name = _options.CurrentValue.UserName;
  26. return Name;
  27. }
  28. }
  29. public void ConfigureServices(IServiceCollection services)
  30. {
  31. services.AddControllersWithViews();
  32. services.Configure<AppOptions>(Configuration.GetSection("AppOptions"));
  33. services.AddSingleton<UserService>();
  34. }
  • 上面的UserService是单例注入的,通过IOptionsMonitor<T>的方式是可以实现配置实时刷新的,而IOptionsSnapshot<T>启动就会报错。

多个配置文件加载实时生效

  • 增加多一个db配置文件
  • 修改Program.cs处CreateHostBuilder(),也是加载时加上reloadOnChange:true 就可以了。
  1. public static IHostBuilder CreateHostBuilder(string[] args) =>
  2. Host.CreateDefaultBuilder(args)
  3. .ConfigureAppConfiguration((context, config) =>
  4. {
  5. config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
  6. config.AddJsonFile("Configs/dbsetting.json", optional: true, reloadOnChange: true);
  7. })
  8. .ConfigureWebHostDefaults(webBuilder =>
  9. {
  10. webBuilder.UseStartup<Startup>();
  11. });
  • 使用也是一样的:
  1. public class HomeController : Controller
  2. {
  3. private readonly ILogger<HomeController> _logger;
  4. private readonly IConfiguration _configuration;
  5. private AppOptions _options;
  6. public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IOptionsMonitor<AppOptions> appOptions)
  7. {
  8. _logger = logger;
  9. _configuration = configuration;
  10. _options = appOptions.CurrentValue;
  11. }
  12. public IActionResult Index()
  13. {
  14. string Name = _configuration["TestSetting"];
  15. string Name2 = _configuration["db:connection1"];
  16. ViewBag.Name = Name;
  17. ViewBag.Name2 = Name2;
  18. return View();
  19. }
  20. }