回答这个问题的关键是要知道密钥是如何生成的。在您的情况下,键/值对将是:
DynamicConfig:Features:0:Type
DynamicConfig:Features:0:Options:MaxFileSize
DynamicConfig:Features:1:Type
DynamicConfig:Features:1:Options:MinAge
DynamicConfig:Features:1:Options:MaxAge
DynamicConfig:Features:2:Type
DynamicConfig:Features:2:Options:MinAge
DynamicConfig:Features:2:Options:MaxAge
注意数组的每个元素是如何表示的DynamicConfig:Features:{i}
.
第二件事要知道的是,您可以将配置的任何部分映射到对象实例,方法是ConfigurationBinder.Bind method:
var conf = new PersonCheckerOption();
Configuration.GetSection($"DynamicConfig:Features:1:Options").Bind(conf);
当我们将所有这些放在一起时,我们可以将您的配置映射到您的数据结构:
services.Configure<FeaturesOptions>(opts =>
{
var features = new List<FeatureConfig>();
for (var i = 0; ; i++)
{
// read the section of the nth item of the array
var root = $"DynamicConfig:Features:{i}";
// null value = the item doesn't exist in the array => exit loop
var typeName = Configuration.GetValue<string>($"{root}:Type");
if (typeName == null)
break;
// instantiate the appropriate FeatureConfig
FeatureConfig conf = typeName switch
{
"FileSizeChecker" => new FileSizeCheckerOptions(),
"PersonChecker" => new PersonCheckerOption(),
_ => throw new InvalidOperationException($"Unknown feature type {typeName}"),
};
// bind the config to the instance
Configuration.GetSection($"{root}:Options").Bind(conf);
features.Add(conf);
}
opts.Features = features.ToArray();
});
注意:所有选项必须源自FeatureConfig
为了这个工作(例如public class FileSizeCheckerOptions : FeatureConfig
)。您甚至可以使用反射来自动检测继承自的所有选项FeatureConfig
,以避免类型名称的切换。
注 2:您还可以将您的配置映射到Dictionary
, or a dynamic
如果您愿意,可以反对;看我的回答将 netcore IConfigurationSection 绑定到动态对象.