.NET 5 設定変更後に再起動せず自動反映

.NET 5 設定変更後に再起動せず自動反映

.NET Core、.NET5のデフォルト設定は一度だけ読み込まれ、設定を変更するたびに再起動が必要です。どのようにすれば即座に反映させることができますか?

最終更新 2021/09/18 11:35
包子wxl
読了目安 3 分
カテゴリ
ASP.NET Core
タグ
.NET C# ASP.NET Core 設定ファイル

一、設定ファイルのリアルタイム反映

1.1 設定

Program.csCreateHostBuilder() で設定ファイルを読み込む際に、reloadOnChange: true を指定します。

これにより、設定ファイルが変更されるとプログラムがファイルの変更を検知し、自動的に再読み込みを行うようになります。

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 検証

appsettings.json の内容は以下の通りです。

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

コード:

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();
    }
}

画面表示:

設定ファイルを次のように変更します。

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

ページを更新すると、変更が反映されています。

1.3 IOptions 方式によるリアルタイム反映

AppOptions.cs クラスを新規作成します。

/// <summary>
/// 設定ファイル
/// </summary>
public class AppOptions
{
    public string UserName { get; set; }
}

Startup.cs で設定を Options に追加します。

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

使用例:

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();
    }
}

IOptions には3つの方法があります。

1. IOptions<T>          // サイト起動後、取得する値は常に変わらない
2. IOptionsMonitor<T>   // サイト起動後、設定ファイルに変更があるとイベントを発行する(設定読み込み時 reloadOnChange:true が必須)
3. IOptionsSnapshot<T>  // サイト起動後、毎回設定ファイルの最新値を取得する(設定読み込み時 reloadOnChange:true が必須)

注意:

IOptionsMonitor<T>IOptionsSnapshot<T> の最大の違いは、前者は他の Singleton Services で使用できるのに対し、後者はできないことです。前者は Singleton として登録され、後者は Scoped として登録されるため、ファイルが変更されると前者は即座に Reload されるのに対し、後者は各リクエストのタイミングで Reload されます。

例:

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>();
}

上記の UserService はシングルトンとして注入されています。IOptionsMonitor<T> を使用すれば設定のリアルタイム更新が可能ですが、IOptionsSnapshot<T> では起動時にエラーが発生します。

1.4 複数の設定ファイルの読み込みによるリアルタイム反映

データベース用の設定ファイル(dbsetting.json)を追加します。

Program.csCreateHostBuilder() を修正し、読み込み時に reloadOnChange: true を指定するだけです。

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>();

                });

使用方法も同様です。

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();
    }
}
さらに探索

関連読書

その他の記事