作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有什么方法可以从 appsettings.json
读取多态对象吗?以强类型的方式?下面是我需要的一个非常简化的例子。
我有多个应用组件,名为 Features
这里。这些组件由工厂在运行时创建。我的设计意图是每个组件都由其单独的强类型选项配置。在这个例子中 FileSizeCheckerOptions
和 PersonCheckerOption
是这些的实例。每个功能都可以使用不同的选项多次包含。
但是使用现有的 ASP.NET Core 配置系统,我无法阅读 多晶强类型选项。如果设置是由 JSON 解串器读取的,我可以使用 something like this .但这不是appsettings.json
的情况,其中选项只是键值对。
appsettings.json
{
"DynamicConfig":
{
"Features": [
{
"Type": "FileSizeChecker",
"Options": { "MaxFileSize": 1000 }
},
{
"Type": "PersonChecker",
"Options": {
"MinAge": 10,
"MaxAge": 99
}
},
{
"Type": "PersonChecker",
"Options": {
"MinAge": 15,
"MaxAge": 20
}
}
]
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<FeaturesOptions>(Configuration.GetSection("DynamicConfig"));
ServiceProvider serviceProvider = services.BuildServiceProvider();
// try to load settings in strongly typed way
var options = serviceProvider.GetRequiredService<IOptions<FeaturesOptions>>().Value;
}
其他定义
public enum FeatureType
{
FileSizeChecker,
PersonChecker
}
public class FeaturesOptions
{
public FeatureConfig[] Features { get; set; }
}
public class FeatureConfig
{
public FeatureType Type { get; set; }
// cannot read polymorphic object
// public object Options { get; set; }
}
public class FileSizeCheckerOptions
{
public int MaxFileSize { get; set; }
}
public class PersonCheckerOption
{
public int MinAge { get; set; }
public int MaxAge { get; set; }
}
最佳答案
回答这个问题的关键是要知道 key 是如何生成的。在您的情况下,键/值对将是:
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
将配置的任何部分映射到对象实例。方法:
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
继承的所有选项。 , 以避免切换类型名称。
Dictionary
,或
dynamic
如果您愿意,可以反对;查看我对
Bind netcore IConfigurationSection to a dynamic object 的回答.
关于c# - 如何在 appsettings.json 中加载多态对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55954858/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!