【问题标题】:Add to .NET Core Configuration Later in the Program稍后在程序中添加到 .NET Core 配置
【发布时间】:2018-11-16 19:31:07
【问题描述】:

这是我的 .NET Core 应用程序的设置:

 public class Program
 {
     public static void Main(string[] args)
     {
         BuildWebHost(args).Run();
     }

     public static IWebHost BuildWebHost(string[] args)
     {
         return WebHost.CreateDefaultBuilder(args)
             .UseKestrel()
             .UseContentRoot(Directory.GetCurrentDirectory())
             .UseIISIntegration()
             .ConfigureAppConfiguration((builderContext, config) =>
             {
                 var entryAssemblyFolder = new FileInfo(Assembly.GetEntryAssembly().Location).DirectoryName;
                 IHostingEnvironment env = builderContext.HostingEnvironment;
                 config
                     .SetBasePath(entryAssemblyFolder)
                     .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
             })
             .UseStartup<Startup>()
             .Build();
     }
 }

 public class Startup
 {
     public Startup(IConfiguration configuration)
     {
         Configuration = configuration;
     }

     public static IConfiguration Configuration { get; set; }
 }

以上所有内容在程序启动时运行。在程序执行期间的稍后时间点,我希望能够根据启动时未知的数据添加额外的配置。以下是伪代码,因为 ConfigurationBuilder 构造函数没有参数:

public class Helper
 {
     public void Add(string key, string value)
     {
         //pseudo-code:
         var builder = new ConfigurationBuilder(Startup.Configuration);  

         builder.AddInMemoryCollection(new List<KeyValuePair<string, string>>
         {
             new KeyValuePair<string, string>(key, value)
         });

         Startup.Configuration = builder.Build();
     }
 }

如何在保留现有配置的同时添加现有配置(包括 reloadOnChange: true)?

谢谢,

【问题讨论】:

  • 似乎对 AddInMemoryCollection 方法的作用存在误解。内存中的集合是配置的数据提供者,最好在实际构建配置之前设置它。重新创建构建器违背了动态重新加载配置更改的目的。 Official documentation
  • 我同意。我不想想要重建。我这样做是为了代替我要求的适当解决方案。

标签: configuration .net-core


【解决方案1】:

我对@9​​87654321@ 的来源做了更多的挖掘。提供者将初始数据复制到它自己的 Data 属性中。

因此,即使您更新了原始字典,提供程序在初始化时仍然只有原始值。

尚未尝试可能有效的GetReloadToken 方法,但这里有另一种更直接的方法。

认为这是您的配置:

    public class MyConfiguration
    {

        public static Dictionary<string,string> InMemoryCollection =
        new Dictionary<string, string>
        {
            {"InMemoryCollection:Option1", "value1"},
            {"InMemoryCollection:Option2", "value2"}
        };
    }

初始化你的配置:

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration(builder => {
                builder.AddInMemoryCollection(MyConfiguration.InMemoryCollection);
            })
            .UseStartup<Startup>();

假设您有一个控制器来读取和输入新值:

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private IConfigurationRoot configuration;

        /// <summary>
        /// Initializes a new instance of the <see cref="ValuesController"/> class.
        /// Value injected through DI.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        public ValuesController(IConfiguration configuration)
        {
            this.configuration = (IConfigurationRoot)configuration;
        }

        [HttpGet]
        /// <summary>
        /// Get in memory values.
        /// </summary>
        /// <returns></returns>
        public IDictionary<string,string> Get()
        {
            var result = new Dictionary<string, string>();
            this.configuration.GetSection("InMemoryCollection").Bind(result);
            return result;
        }

        [HttpPost]
        /// <summary>
        /// Enter a new value.
        /// </summary>
        /// <param name="value">The value.</param>
        public void Post([FromBody] string value)
        {
            //get the provider instance from the configuration root.
            MemoryConfigurationProvider memoryProvider =
                (MemoryConfigurationProvider)this.configuration.Providers
                    .First(p =>
                        p.GetType() == typeof(MemoryConfigurationProvider));

            //add the new option into the providers data collection.
            var nextKey = MyConfiguration.InMemoryCollection.Count + 1;

            memoryProvider.Add(
                $"InMemoryCollection:Option{nextKey}",
                value);
        }
    }

注意:我不知道动态添加的配置选项的详细信息/要求,但使用 AddInMemoryCollection 方法看起来并不是最好的选择。当然,除非你故意不想坚持它们。 我相当肯定还有其他方法/解决方案可以解决此问题,而不必使用 Microsoft.Extensions.Configuration API。

【讨论】:

    猜你喜欢
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多