сам метод может запрашивать зависимости, верно @poke?

ользую ASP.NET Core 2.0, и у меня есть код конфигурации, как это вMain метод:

public static void Main(string[] args)
{
    var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
    var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{environment ?? "Production"}.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .Build();
}

у меня естьreloadOnChangустановлен в true, и в моем контроллере я используюIOptionsSnapshot

public HomeController(ILogger<HomeController> logger, IOptionsSnapshot<AppSettings> options)

Но когда я изменяю значения в моемappsettings.jsonЯ должен перезапускать свое приложение каждый раз, или изменения не регистрируются просто обновлением браузера. Что я делаю неправильно? Я пытался запустить приложение как с консоли, так и с IIS Express; Я также пыталсяIOptionsMonitor, то же самое. Кстати, в чем разница междуIOptionsMonitor а такжеIOptionsSnapshot?

 poke04 окт. 2017 г., 18:24
Как вы регистрируетеAppSettings параметры?
 Ray Fan04 окт. 2017 г., 18:42
Я добавил AppSettings в Startup.cs, как эти сервисы. Настроить <AppSettings> (Configuration.GetSection ("AppSettings"));

Ответы на вопрос(1)

Решение Вопроса

Как уже упоминалось вдокументация, просто включивreloadOnChange а затем вводитьIOptionsSnapshot<T> вместоIOptions<T> будет достаточно. Это требует, чтобы вы правильно настроили этот типT хотя. Обычно регистрация конфигурации будет выглядеть так:

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

Однако, если присмотреться к вашему коду, то не похоже, что вы используете новый способ конфигурирования вашей программы ASP.NET Core 2.0. Конфигурация теперь является частью внедрения зависимостей, поэтому вы настроите ее как частьWebHostBuilder, с помощьюConfigureAppConfiguration, Это может выглядеть, например, так:

public static IWebHost BuildWebHost()
    => new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((builderContext, config) =>
        {
            IHostingEnvironment env = builderContext.HostingEnvironment;

            config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
        })
        .UseStartup<Startup>()
        .Build();

Если вы используете сборщик по умолчанию, используяWebHost.CreateDefaultBuilder()тогда вам даже не нужно это делать, так как конфигурация автоматически настраивается такreloadOnChange активируется.

Разница междуIOptionsSnapshot а такжеIOptionsMonitor это то, чтоIOptionsSnapshot просто даст вамснимок из вариантов в то времяIOptionsSnapshot<T> объект строится.

Вот почему использование точно так же, как сIOptions<T>: Вы вводите его в конструктор, а затем сохраняетеoptions.Value в случае, чтобы получить доступ к параметрам позже. В этот момент этот объект зафиксирован и никогда не изменится. ПростоIOptionsSnapshot<T> регистрируется как зависимая область видимости вместо одноэлементной зависимости, такой какIOptions<T>Таким образом, он получает возможность получать текущие значения конфигурации для каждого запроса, а не только один раз.

IOptionsMonitor<T> однако это одноэлементная служба, которая позволяет вам получить текущее значение конфигурации в любой момент времени. Так что это особенно полезно для одноуровневых сервисов, которым необходимо получать текущую конфигурацию всякий раз, когда им это нужно. Кроме того, монитор опций предлагаеттолкающий механизм получать уведомления об изменениях конфигурации от источников конфигурации. Таким образом, вы можете явно обрабатывать изменения конфигурации.

Моментальные снимки параметров предназначены для использования в переходных или ограниченных зависимостях, поэтому вы будете в порядке, если будете использовать их большую часть времени. Только в редких случаях, когда выимеют использовать единый сервис, которыйтакже должна иметь самую последнюю конфигурацию, вам необходимо использовать монитор параметров. В этих случаях обратите внимание, что простого переключения со снимков на монитор будет недостаточно. Обычно вам придется каким-то образом обрабатывать измененную конфигурацию (например, очистить состояние, очистить кэш и т. Д.). Поэтому вы всегда должны думать о том, нужна ли вам перезагрузка конфигурации длявсе или если просто перезапуск приложения не является жизнеспособной альтернативой.

 Ray Fan04 окт. 2017 г., 19:14
Спасибо тыкаешь за ответ! Я обновил свой конфигурационный код, как ваш, и AppSettings в моем контроллере сработали. Однако у меня есть этот код в конструкторе промежуточного программного обеспечения, который все еще не принимает изменения, общедоступный MyMiddleware (параметры RequestDelegate next, IOptionsSnapshot <AppSettings>, ILoggerFactory loggerFactory), знаете ли вы, должно ли промежуточное программное обеспечение реагировать на изменения конфигурации, как это сделали бы контроллеры?
 ssmith05 дек. 2017 г., 16:10
Вам не нужно использоватьGetRequiredService внутриInvoke метод в промежуточном программном обеспечении, так какInvoke сам метод может запрашивать зависимости, верно @poke?
 Ray Fan04 окт. 2017 г., 22:07
Привет, @poke. Я запустил его в промежуточном программном обеспечении с параметрами var settings = context.RequestServices.GetService <IOptionsSnapshot <AppSettings >> (). Value; Повлияет ли этот код GetService на производительность, если каждый запрос поступает в это промежуточное ПО? И наконец, есть ли способ получить объект AppSettings в методе ConfigureServices при запуске? Спасибо!
 poke04 окт. 2017 г., 20:00
@fanray Да, к сожалению, промежуточное ПО - это совсем другое. Middleware настроенодин раз когда приложение запускается иStartup.Configure метод выполнен. Таким образом, все зависимости разрешаются в это время, а экземпляры промежуточного программного обеспечения хранятся как общие экземпляры. Таким образом, вы не можете ввести параметры там. Вам придется разрешить варианты в пределахInvoke метод, например, используяcontext.RequestServices.GetRequiredService<IOptionsSnapshot<AppSettings>>().
 poke04 окт. 2017 г., 22:22
Нет,GetService Вызов call должен быть почти таким же, как ввод его в конструктор. Просто ДИ архитектурно лучше по сравнению сGetService вызовы (которые называются «шаблоном поиска услуг»). Но иногда вы просто не можете избежать этого. Btw. если вы обнаружите, что запрашиваете более одной службы, рассмотрите возможность создания службы обработчика, которую затем запрашиваете в промежуточном программном обеспечении. Этот сервис-обработчик может затем использовать обычный DI для доступа к вещам (включая снимки параметров).

Ваш ответ на вопрос