Параметры перезагрузки с помощью reloadOnChange в ASP.NET Core - PullRequest
0 голосов
/ 29 июня 2018

В моем приложении ASP.NET Core я связываю appsettings.json со строго типизированным классом AppSettings .

public Startup(IHostingEnvironment environment)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(environment.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{environment.EnvironmentName}.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables();

    Configuration = builder.Build();
}

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<AppSettings>(Configuration);
    //...
}

В одном классе я обертываю этот класс AppSettings следующим образом:

public class AppSettingsWrapper : IAppSettingsWrapper
{
    private readonly IOptions<AppSettings> _options;

    public AppSettingsAdapter(IOptions<AppSettings> options)
    {
        _options = options ?? throw new ArgumentNullException("Options cannot be null");
    }

    public SomeObject SomeConvenienceGetter()
    {
        //...
    }
}

Теперь я пытаюсь перезагрузить AppSettings, если файл json изменится. Я где-то читал, что класс IOptionsMonitor может обнаруживать изменения, но в моем случае это не работает.

Я пытался вызвать событие OnChange , например, для тестирования:

public void Configure(IApplicationBuilder applicationBuilder, IOptionsMonitor<AppSettings> optionsMonitor)
{
    applicationBuilder.UseStaticFiles();
    applicationBuilder.UseMvc();

    optionsMonitor.OnChange<AppSettings>(vals => 
    {
        System.Diagnostics.Debug.WriteLine(vals);
    });
}

Событие никогда не вызывается, когда я меняю файл json. Кто-нибудь знает, что я могу изменить, чтобы заставить механику перезагрузки работать в моем сценарии?

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Что вы можете сделать, это создать свой класс-оболочку вокруг класса config, как вы это делали в AppSettingsWrapper , и внедрить IOptionsMonitor. Затем сохраните частную собственность вашего класса настроек. Эта оболочка может быть введена как одиночная, и IOptionsMonitor будет отслеживать ваши изменения.

public class AppSettingsWrapper
{
    private AppSettings _settings;

    public AppSettingsWrapper(IOptionsMonitor<AppSettings> settings)
    {
        _settings = settings.CurrentValue;

        // Hook in on the OnChange event of the monitor
        settings.OnChange(Listener);
    }

    private void Listener(AppSettings settings)
    {
        _settings = settings;
    }

    // Example getter
    public string ExampleOtherApiUrl => _settings.ExampleOtherApiUrl;
}

Затем зарегистрируйте свой класс-оболочку как синглтон

services.AddSingleton(sp => new AppSettingsWrapper(sp.GetService<IOptionsMonitor<AppSettings>>()));
0 голосов
/ 29 июня 2018

Вам нужно ввести IOptionsSnapshot<AppSettings>, чтобы перезагрузка заработала.

К сожалению, вы не можете загрузить IOptionsSnapshot в службу Singleton. IOptionsSnapshot является услугой Scoped, поэтому вы можете ссылаться на нее только в зарегистрированном классе Scoped или Transient.

Но, если подумать, это имеет смысл. Настройки должны быть перезагружены при их изменении, поэтому, если вы внедрите их в Singleton, класс никогда не получит обновленные настройки, потому что конструктор не будет вызываться снова для Singleton.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...