带有 IOptionsSnapshot 的 ASP.NET Core 配置 reloadOnChange 仍然没有响应 [英] ASP.NET Core configuration reloadOnChange with IOptionsSnapshot still not responsive

查看:14
本文介绍了带有 IOptionsSnapshot 的 ASP.NET Core 配置 reloadOnChange 仍然没有响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ASP.NET Core 2.0,并且在 Main 方法中有这样的配置代码:

I'm using ASP.NET Core 2.0 and I have configuration code like this in the Main method:

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

我将 reloadOnChange 设置为 true,并且在我的控制器中我使用的是 IOptionsSnapshot;

I have the reloadOnChange set to true, and in my controller I am using IOptionsSnapshot;

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

但是当我修改我的 appsettings.json 中的值时,我必须每次都重新启动我的应用程序,否则仅通过刷新浏览器就无法获取更改.我究竟做错了什么?

But when I modify the values in my appsettings.json, I have to restart my app every time or the changes are not being picked up just by refreshing the browser. What am I doing wrong?

我尝试使用控制台和 IIS Express 运行该应用程序;我也试过 IOptionsMonitor,同样的事情.IOptionsMonitorIOptionsSnapshot 有什么区别?

I've tried to run the app both with console and IIS Express; I've also tried IOptionsMonitor, same thing. What is the difference between IOptionsMonitor and IOptionsSnapshot?

推荐答案

文档,只需启用 reloadOnChange 然后注入 IOptionsSnapshot 而不是 IOptions 就足够了.这需要您正确配置该类型 T .通常配置注册将如下所示:

As mentioned in the documentation, just enabling reloadOnChange and then injecting IOptionsSnapshot<T> instead of IOptions<T> will be enough. That requires you to have properly configured that type T though. Usually a configuration registration will look like this:

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

但是,仔细观察您的代码,您似乎并没有使用新的 ASP.NET Core 2.0 方式来配置您的程序.该配置现在是依赖注入的一部分,因此您将使用 ConfigureAppConfiguration 将其设置为 WebHostBuilder 的一部分.例如,这可能如下所示:

However, looking closer at your code, it does not seem that you are using the new ASP.NET Core 2.0 way of configuring your program. The configuration is now part of dependency injection, so you will set it up as part of the WebHostBuilder, using ConfigureAppConfiguration. That could for example look like this:

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 激活.

If you are using the default builder using WebHost.CreateDefaultBuilder(), then you don’t even need to do this, as the configuration is then automatically set up like that with reloadOnChange activated.

IOptionsSnapshotIOptionsMonitor 的区别在于 IOptionsSnapshot 只会为您提供选项的快照在构造 IOptionsSnapshot<T> 对象时.

The difference between IOptionsSnapshot and IOptionsMonitor is that the IOptionsSnapshot will just give you a snapshot of the options at the time the IOptionsSnapshot<T> object is being constructed.

这就是为什么用法与 IOptions<T> 完全相同的原因:您将其注入构造函数中,然后将 options.Value 存储在实例中以访问稍后的选项.那时,该对象是固定的,永远不会改变.只是 IOptionsSnapshot<T> 被注册为范围依赖而不是像 IOptions<T> 这样的单例依赖,因此它有机会获取当前配置值在每个请求上而不是一次.

That’s why the usage is exactly the same as with IOptions<T>: You inject it in the constructor and then store the options.Value in the instance to access the options later. At that point, that object is fixed and will never change. It’s just that the IOptionsSnapshot<T> is registered as a scoped dependency instead of a singleton dependency like IOptions<T>, so it gets the chance to get the current configuration values on every request instead of just once.

IOptionsMonitor<T> 是一个单例服务,允许您在任何给定时间检索当前配置值.因此,对于需要在需要时获取当前配置的单例服务特别有用.此外,选项监视器提供了一种推送机制,以获取配置源的配置更改通知.这样,您可以显式处理配置更改.

The IOptionsMonitor<T> however is a singleton service that allows you to retrieve the current configuration value at any given time. So it is especially useful for singleton services that need to get the current configuration whenever they need it. In addition, the options monitor offers a push mechanism to get notified of configuration changes by the configuration sources. That way, you can explicitly handle configuration changes.

选项快照旨在用于瞬态或范围依赖项,因此您在大多数情况下使用它们就可以了.只有在极少数情况下,当您必须使用单例服务需要具有最新配置时,您才需要使用选项监视器.在这些情况下,请注意仅从快照切换到监视器是不够的.通常,您必须以某种方式处理更改的配置(例如清理状态、清除缓存等).因此,您应该始终考虑您是否真的需要为所有内容重新加载配置,或者只是重新启动应用程序不是一个可行的选择.

Options snapshots are designed to be used for transient or scoped dependencies, so you will be fine just using those most of the time. Only in rare occasions when you have to use a singleton service that also needs to have the most updated configuration, you should have the need to use an options monitor. In those cases, note that just switching from snapshots to a monitor will not be enough. Usually, you will have to handle changed configuration in some way (for example clean up state, clear caches etc.). So you should always think about whether you actually need reloadable configuration for everything or if just restarting the application isn’t a viable alternative.

这篇关于带有 IOptionsSnapshot 的 ASP.NET Core 配置 reloadOnChange 仍然没有响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆