NET 5 configuration modifications will take effect automatically without restarting

NET 5 configuration modifications will take effect automatically without restarting

The default configuration of. NET Core and. NET5 is loaded only once. When modifying the configuration, you need to restart before it takes effect. How can the modification take effect immediately?

最后更新 9/18/2021 11:35 AM
包子wxl
预计阅读 4 分钟
分类
ASP.NET Core
标签
.NET C# ASP.NET Core profile

1. Set the configuration file to take effect in real time

1.1 configured

Add reloadOnChange:true when loading configuration files at CreateHostBuilder() in Program.cs.

In this way, when the configuration file is modified, the program will detect the change in the file and automatically reload it.

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();

            });

1.2 verification

The appsettings.json file contains the following

{
  "TestSetting": "123",
  "AppOptions": {
    "UserName": "zhangsan"
  }
}

Code:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IConfiguration _configuration;
    public HomeController(ILogger<HomeController> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    public IActionResult Index()
    {
        string Name = _configuration["TestSetting"];
        string Name2 = _configuration["AppOptions:UserName"];
        ViewBag.Name = Name;
        ViewBag.Name2 = Name2;
        return View();
    }
}

The interface displays:

Modify the configuration file to:

{
  "TestSetting": "abc",
  "AppOptions": {
    "UserName": "zhangsan123"
  }
}

Refresh the page, changes have occurred:

1.3 IOptions method takes effect in real time

New AppOptions.cs class

/// <summary>
/// 配置文件
/// </summary>
public class AppOptions
{
    public string UserName { get; set; }
}

Add configuration to Options at Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.Configure<AppOptions>(Configuration.GetSection("AppOptions"));
}

Use:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IConfiguration _configuration;
    private IOptionsMonitor<AppOptions> _options;

    public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IOptionsMonitor<AppOptions> appOptions)
    {
        _logger = logger;
        _configuration = configuration;
        _options = appOptions;
    }

    public IActionResult Index()
    {
        string Name = _configuration["TestSetting"];
        string Name2 = _options.CurrentValue.UserName;
        ViewBag.Name = Name;
        ViewBag.Name2 = Name2;
        return View();
    }
}

There are three ways to IOptions

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

** Note: **

The biggest difference between IOptionsMonitor T and IOptionsSnapshot T is that the former can be used by other Singleton Services while the latter cannot, because the former is registered as Singleton and the latter is registered as Scoped, which means that if a file is modified, the former will be redirected immediately, while the latter will be redirected every request.

Example:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private UserService _userService;

    public HomeController(ILogger<HomeController> logger, UserService userService)
    {

        _userService = userService;
    }

    public IActionResult Index()
    {
        string Name2 = _userService.GetName();
        ViewBag.Name2 = Name2;
        return View();
    }
}
public class UserService
{
    private IOptionsMonitor<AppOptions> _options;

    public UserService(IOptionsMonitor<AppOptions> appOptions)
    {
        _options = appOptions;
    }

    public string GetName()
    {
        var Name = _options.CurrentValue.UserName;
        return Name;
    }
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.Configure<AppOptions>(Configuration.GetSection("AppOptions"));
    services.AddSingleton<UserService>();
}

The UserService above is injected in a single case. Real-time configuration refresh can be achieved through IOptionsMonitor T, and an error will be reported when IOptionsSnapshot T is activated.

1.4 Multiple configuration files are loaded and effective in real time

Add one more db configuration file

Modify CreateHostBuilder() at Program.cs, and add reloadOnChange:true when loading.

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                config.AddJsonFile("Configs/dbsetting.json", optional: true, reloadOnChange: true);
            })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();

                });

The same is true for use:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IConfiguration _configuration;
    private AppOptions _options;
    public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IOptionsMonitor<AppOptions> appOptions)
    {
        _logger = logger;
        _configuration = configuration;
        _options = appOptions.CurrentValue;
    }

    public IActionResult Index()
    {
        string Name = _configuration["TestSetting"];
        string Name2 = _configuration["db:connection1"];
        ViewBag.Name = Name;
        ViewBag.Name2 = Name2;
        return View();
    }
}
Keep Exploring

延伸阅读

更多文章