每次在 .NET Core 1.1 控制台应用程序中更改时,如何在运行时重新加载 appsettings.json?

How to reload appsettings.json at runtime each time it changes in .NET core 1.1 console application?

我试图重现 this great article by Andrew Lock 中描述的方法。但是,我无法在 .NET core 1.1 控制台应用程序中获得此 运行。更改并保存 appsettings.json 文件后,如果不重新启动应用程序,则更改不会反映在应用程序中。

涉及多个文件,所以我创建了我能想到的最小示例 on github。我还在 github.

的 README.MD 文件中提供了详细信息

如果能帮助解决这个问题,我们将不胜感激。请记住,我是 .NET Core 的新手,而不是经验丰富的开发人员。这是我关于 Whosebug 的第一个问题...提前致谢!

要理解的关键是范围

ASP.NET核心中有三种作用域——瞬态、作用域和单例。 IOptionsSnapshot 配置为 范围 服务。

在 ASP.NET Core 中,每个请求都会启动一个作用域,因此每个请求,您都会获得一个 IOptionsSnapshot 的新实例,其中包含更新的配置值。

在您提供的示例中,您正在创建一个 IServiceProvider,并直接从顶级提供程序获取 IMyService 的实例:

IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();


while (true)
{
    var service = serviceProvider.GetService<IMyService>();
    var reply = service.DoSomething();

    Console.WriteLine(reply);
}

本质上,您始终对服务提供商的每个请求使用相同的范围,因此您始终获得相同的 IOptionsSnapshot 实例。实际上,如果您从不创建新范围,那么您所有范围内的服务都会变成单例!

解决此问题的方法是在每次获取服务时创建一个新范围:

IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();


while (true)
{
    using (var scope = serviceProvider.CreateScope())
    {
        var service = scope.ServiceProvider.GetService<IMyService>();
        var reply = service.DoSomething();

        Console.WriteLine(reply);
    }
}

如果您在 ASP.NET Core 应用程序(或控制台应用程序)中的请求上下文之外执行诸如创建 EF Core DbContext 之类的操作,这一点也变得很重要。在访问服务提供商的服务之前始终创建一个新范围!

P.S。我创建了一个拉取请求来修复你的示例:)