首页 > 解决方案 > 在没有 DI 的控制台应用程序中将 IConfigurationSection 与可刷新配置绑定

问题描述

我在 .Net Core 控制台应用程序中使键入的配置可刷新时遇到问题。

该应用程序将从配置中加载类型化的对象...

{
     "LibrarySettings": {
       "SettingA": "ValueA",
       "SettingB": "ValueB"
     }
}

...并将它们传递给图书馆IOption<SomeLibrarySettings>

public class LibrarySettings
{
    public string SettingA { get; set; }
    public string SettingB { get; set; }
}

public class BusinessLogic
{
    private IOptions<LibrarySettings> _settings;

    public BusinessLogic(IOptions<LibrarySettings> settings)
    {
        _settings = settings;
    }

    public string GetValueA => _settings.Value.SettingA;

    public string GetValueB => _settings.Value.SettingB;
}

在运行时,如果我更改appsettings.json,我会期望底层IOptions实例相应地更新值。

public class Program
{
    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", false, true);

        var configuration = builder.Build();

        LibrarySettings settings = new LibrarySettings();

        configuration.Bind("LibrarySettings", settings);

        BusinessLogic logic = new BusinessLogic(Options.Create(settings));

        while (true)
        {
            configuration.Reload();
            Console.WriteLine();
            Console.WriteLine(logic.GetValueA);
            Console.WriteLine(logic.GetValueB);
            Console.ReadLine();
        }
    }
}

不幸的是,事实并非如此。当我启动此代码并更改appsettings.json应用程序中的值复制的值时,不会重新加载。

我究竟做错了什么?

标签: c#.net-core.net-standard

解决方案


使用IOptionsSnapshotinsted ofIOptions

public class BusinessLogic
{
     private IOptionsSnapshot<LibrarySettings> _settings;

     public BusinessLogic(IOptionsSnapshot<LibrarySettings> settings)
     {
         _settings = settings;
     }

     public string GetValueA => _settings.Value.SettingA;

     public string GetValueB => _settings.Value.SettingB;
 }

参考ASP.NET Core 中的选项模式

编辑:避免常见错误('T' must be a non-abstract type with a public parameterless constructor

public class LibrarySettings
{
    public string SettingA { get; set; }
    public string SettingB { get; set; }
    public LibrarySettings() {}
}

让它工作:

class Program
    {

        static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", false, true);

            var configuration = builder.Build();

            var settings = new LibrarySettings();

            configuration.GetSection("LibrarySettings").Bind(settings);

            var x = settings.SettingA;
        }

    }

    public class BusinessLogic
    {
        private LibrarySettings _settings;

        public BusinessLogic(IOptionsSnapshot<LibrarySettings> settings)
        {
            _settings = settings.Value;
        }

        public string GetValueA => _settings.SettingA;

        public string GetValueB => _settings.SettingB;
    }
    public class LibrarySettings
    {
        public string SettingA { get; set; }
        public string SettingB { get; set; }
        public LibrarySettings() { }
    }

推荐阅读