如何在 dotnet core 3 控制台应用程序中更改时重新加载“appsettings.json”

Posted

技术标签:

【中文标题】如何在 dotnet core 3 控制台应用程序中更改时重新加载“appsettings.json”【英文标题】:How to reload 'appsettings.json' upon change in a dotnet core 3 console app 【发布时间】:2020-03-11 19:31:25 【问题描述】:

我正在尝试设置一个控制台应用程序来重新加载“appsettings.json”,但我无法让它对文件的更改做出反应。

我已经这样设置了 main:

private static void Main ()
    
        configuration = LoadConfiguration ();

        var services = ConfigureServices ();

        var serviceProvider = services.BuildServiceProvider ();

        serviceProvider.GetService<ConsoleApp> ().Run ();
    

    private static IConfiguration LoadConfiguration ()
        => new ConfigurationBuilder ().SetBasePath (GetApplicationDirectory ())
                                      .AddJsonFile (_APP_SETTING_FILE_NAME, optional: false, reloadOnChange: true)
                                      .Build ();

    private static IServiceCollection ConfigureServices ()
    
        IServiceCollection services = new ServiceCollection ();

        configuration.Bind (new AppSettings ()); // binds the 'appsettings.json' to the class

        services.AddSingleton (configuration);
        services.AddTransient<ConsoleApp> ();

        services.AddOptions<AppSettings> ();  // adds the IOption<T> and IOptionMonitor<T>

        // here I'm trying to follow a post from Dino Esposito [https://www.red-gate.com/simple-talk/dotnet/net-development/asp-net-core-3-0-configuration-factsheet/][1] but services.Configure<AppSettings>() does not compile
        // the failure could be here? :-(
        services.Configure<AppSettings> (opt => opt.Default = configuration["Default"]);

        return services;
    

我很确定我在 DI 的配置中做错了什么,但我不知道是什么。

控制台应用程序很简单,应该注册cahgne但没有,反正这里是

public class ConsoleApp

    public AppSettings AppSettings  get; 

    public ConsoleApp (IOptionsMonitor<AppSettings> appSettingsOptionsMonitor)
    
        AppSettings = appSettingsOptionsMonitor.CurrentValue;

        appSettingsOptionsMonitor.OnChange ((arg1, arg2) => Console.WriteLine ($"\t ---> AppSettings changed to 'arg1.Default' - 'arg2'"));

        Console.WriteLine ($"ctor - appsettings current value: 'AppSettings.Default'.\n");
    

    public void Run ()
    
        Console.WriteLine ($"\tCurrent value: 'AppSettings.Default' - waiting for change ...");

        while (AppSettings.Default != "Stop")  

        Console.WriteLine ($"\t... has changed to 'AppSettings.Default'.");
    

AppSettings 类是:

public class AppSettings

    public string Default  get; set; 

任何帮助将不胜感激!

T'X 彼得

【问题讨论】:

我最近实现了类似的东西,这绝对是一种痛苦。我永远无法获得我所见过的各种 reloadOnChange 方法。我能够做到这一点的唯一方法是直接写入文件,然后使用新的 ServiceCollection 再次调用ConfigureServices。我很想关注这篇文章,看看其他人推荐什么。 .NET Framework 中有一些与此相关的东西尚未进入 .Net Core,如果有的话。 我将添加警告,即在我实施此功能时会出现许多问题,而我上面的架构师认为该功能太容易出错而无法实际使用。最好使用自己的配置文件,而不是 appsettings。 appsettings 错误可能会导致您的服务处于不一致状态或完全崩溃。现在,如果加载辅助配置失败,我们只使用 appsettings 作为备用/默认选项。 【参考方案1】:

您不能使用扩展方法AddOptions 来执行此操作, 因为它不是为与文件配置提供程序一起工作而设计的。 为此,您必须使用类OptionsConfigurationServiceCollectionExtensions中的扩展方法

密钥在OptionsConfigurationServiceCollectionExtensions 类和OptionsMonitor 类中。 在 OptionsMonitor 类的构造函数中可以看到,它会获取服务容器中注册的所有 IOptionsChangeTokenSource 实例,这些实例是通过 OptionsConfigurationServiceCollectionExtensions.Configure 方法注册的。IOptionsChangeTokenSource 实例在下配置文件更改时重新加载选项。

作为比较,您可以在AddOptions 方法中看到,它没有注册 IOptionsChangeTokenSource 实例。

【讨论】:

以上是关于如何在 dotnet core 3 控制台应用程序中更改时重新加载“appsettings.json”的主要内容,如果未能解决你的问题,请参考以下文章

如何验证.net core安装成功

如何运行显示控制台窗口或不基于参数参数的dotnet Core控制台应用程序?

在 Dotnet Core 3.1 中将数据从一个控制器传递到另一个控制器

如何在启动时使用 dotnet core 3 中的依赖项调用自定义服务?

ASP.NET Core分布式项目实战Docker制作dotnet core控制台程序镜像

发布后运行 dotnet core 控制台应用程序