如何在 appsettings.json 中加载多态对象

2023-11-27

有什么方法可以从中读取多态对象appsettings.json以强类型的方式?下面是我需要的一个非常简单的示例。

我有多个应用程序组件,名为Features这里。这些组件是由工厂在运行时创建的。我的设计意图是每个组件都由其单独的强类型选项配置。在这个例子中FileSizeCheckerOptions and PersonCheckerOption都是这些的例子。每个功能都可以通过不同的选项多次包含。

但对于现有的 ASP.NET Core 配置系统,我无法阅读多态性强类型选项。如果设置是由 JSON 反序列化器读取的,我可以使用像这样的东西。但事实并非如此appsettings.json,其中选项只是键值对。

应用程序设置.json

{
    "DynamicConfig":
    {
        "Features": [
            {
                "Type": "FileSizeChecker",
                "Options": { "MaxFileSize": 1000 }
            },
            {
                "Type": "PersonChecker",
                "Options": {
                    "MinAge": 10,
                    "MaxAge": 99
                }
            },
            {
                "Type": "PersonChecker",
                "Options": {
                    "MinAge": 15,
                    "MaxAge": 20
                }
            }
        ]
    }
}

启动.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; }

}

回答这个问题的关键是要知道密钥是如何生成的。在您的情况下,键/值对将是:

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 绑定到动态对象.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 appsettings.json 中加载多态对象 的相关文章

  • 创建 DirectoryEntry 实例以供测试使用

    我正在尝试创建 DirectoryEntry 的实例 以便可以使用它来测试将传递 DirectoryEntry 的一些代码 然而 尽管进行了很多尝试 我还是找不到实例化 DE 并初始化它的 PropertyCollection 的方法 我有
  • 如何将 yii2 Restful api 中两个表的关系数据显示为 json 格式

    我遇到了将两个表中的数据显示为 JSON 格式并在 yii2 Restful api 上工作的问题 这是我的结构数据库 TABLE volunteer volunteer id int 11 NOT NULL auto increment
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • c 中的错误:声明隐藏了全局范围内的变量

    当我尝试编译以下代码时 我收到此错误消息 错误 声明隐藏了全局范围内的变量 无效迭代器 节点 根 我不明白我到底在哪里隐藏或隐藏了之前声明的全局变量 我怎样才能解决这个问题 typedef node typedef struct node
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • App Insights 升级到 2.5 后,Azure 应用服务将无法启动

    我有一个存储库 它使用应用程序洞察来记录有关在 ASP NET 中运行的服务的信息 我们有一些 ASP NET Core 2 0 站点以及一些完整框架的 asp net 4 应用程序 随着应用程序洞察 2 5 的发布 我们在核心站点中获得了
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 将变量分配给另一个变量,并将一个变量的更改反映到另一个变量中

    是否可以将一个变量分配给另一个变量 并且当您更改第二个变量时 更改会瀑布式下降到第一个变量 像这样 int a 0 int b a b 1 现在 b 和 a 都 1 我问这个问题的原因是因为我有 4 个要跟踪的对象 并且我使用名为 curr

随机推荐

  • 如何获取 SVG tspan 元素的宽度

    我正在尝试获取 a 的渲染宽度tspan元素 位于textSVG 中的元素 这是我的标记
  • 通过 URL 打开 Native AIR 应用程序?

    我希望人们能够通过 URL 启动 Native AIR 应用程序 我的 AIR 应用程序会读取其中的一些参数并打开到正确的状态 因此 用例是有人浏览我们的网站 然后单击链接 它将打开本机桌面应用程序以查看与其链接关联的正确内容 我知道 iT
  • 从 Matlab 函数返回多个输出变量

    可以说我有一个功能 function A B C test x y z A 2 x B 2 y C 2 z end 当您按运行时 Matlab 仅返回输出参数中的第一个值 A 在这种情况下 是否有一个命令可以放入我的函数中 自动返回所有函数
  • 捕获 ASP.NET UserControls 中未处理的异常

    我动态加载用户控件 将它们添加到 Web 表单的 Controls 集合中 如果用户控件在渲染时导致未处理的异常 我想隐藏它们 因此 我尝试挂钩每个 UserControl 的 Error 事件 但似乎 UserControl 永远不会像
  • SQLITE - 将行正确转换为列

    我有一个包含产品订单表的数据库 如下所示 order id prod code prod color size quantity 1 SHIRT 001 S 10 1 SHIRT 001 M 7 1 SHIRT 001 L 8 1 SHIR
  • XAMLParseException 让我抓狂!

    这个 XAMLParseException 让我抓狂 我在 Visual Studio 1020 中使用 NET 3 5 这是我的 xaml
  • 准备从 Python 2.x 转换到 3.x

    到目前为止 我们都知道 我希望如此 Python 3 正在慢慢开始取代 Python 2 x 当然 大多数现有代码最终移植还需要很多年的时间 但我们现在可以在 2 x 版本代码中做一些事情 以使切换更容易 显然是在看什么是新的3 x 中的版
  • 让 will_paginate 与 Ajax 配合使用的最佳方法

    如果你谷歌 will paginate 和 ajax 最上面的结果是这篇博文 但是 will paginate 的原作者说不使用这个方法 对 SEO 蜘蛛不利 但我无法让原作者的方法起作用 他的 javascript 杀死了我所有的链接 另
  • Datetime.ToString() C# 未按预期工作

    From msdn看来我可以创建自己的格式Datetime ToString 方法通过使用M m d y等等 但是当我尝试一个时 它没有按预期工作 下面的截图就是问题所在 我正期待着7 29 2015但收到了7 29 2015 为什么 看起
  • PHP:file_exists 与stream_resolve_include_path - 哪个性能更好?

    似乎最近 php 开发人员对使用它是否更好感到好奇文件已存在 or Stream resolve include path 检查文件是否存在时 无论是包含它们 缓存系统等 这让我想知道是否有人做过基准测试 以判断哪一个是更好的选择 无论是页
  • 如何创建异构对象集合?

    我想在 a 中使用特征对象Vec 在 C 中我可以创建一个基类Thing从中派生出Monster1 and Monster2 然后我可以创建一个std vector
  • 无法对没有 data_class 的表单使用回调断言

    我正在创建一个名为 IntervalType 的自定义 FormType 我的 IntervalType 将有两个字段 start and end并且将是整数类型 此自定义 FormType 将始终在不使用的情况下使用data class
  • 将代理与适用于 Java 的 Google HTTP 客户端库结合使用

    我使用 Google HTTP Client Library for Java 发出简单的 JSON 请求并解析响应 当我不通过代理时它效果很好 但现在我想允许我的用户在我的应用程序中使用代理 带有身份验证 功能 我查看了 HttpTran
  • php 5.4 发生字符串偏移量转换

    在以下几行中 我收到错误 发生字符串偏移转换 code value dictionaryAlias value dictionaryText codeLang code value dictionaryAlias value diction
  • SonataAdminBundle 中的自定义操作

    On this page我找到了如何为我的自定义操作添加路线 protected function configureRoutes RouteCollection collection collection gt add ispremium
  • 您可以拥有的 UIApplicationShortcutItem 数量是否有限制?

    我想将新的 3D Force Touch 功能 UIApplicationShortcutItem 添加到我的应用程序中 但我想知道单个应用程序上可以拥有的数量是否有限制 我查看了文档 但没有看到提到限制 https developer a
  • 禁用焦点上的橙色轮廓突出显示

    我正在使用 jQuery jqTouch 和 Phonegap 编写一个应用程序 并且遇到了一个持续存在的问题 当用户使用软键盘上的 Go 按钮提交表单时 就会出现这个问题 尽管通过使用很容易将光标移动到适当的表单输入元素 input el
  • 即使操作系统杀死应用程序,如何在android中保存/恢复全局变量

    在android中 Google建议我们将全局变量保存在Application中 但有一个问题 如果android操作系统因为内存不足而杀死应用程序 应用程序将重新创建 并且我保存的全局变量将丢失 我不知道什么时候保存 恢复这些变量 应用程
  • 如何计算asp.net中数据表列的总和?

    我有一个有 5 列的 DataTable ID Name 帐号 Branch Amount 数据表包含 5 行 如何将标签控件中金额列的总和显示为 总金额 要计算 DataTable 中列的总和 请使用数据表 计算 method 链接的 M
  • 如何在 appsettings.json 中加载多态对象

    有什么方法可以从中读取多态对象appsettings json以强类型的方式 下面是我需要的一个非常简单的示例 我有多个应用程序组件 名为Features这里 这些组件是由工厂在运行时创建的 我的设计意图是每个组件都由其单独的强类型选项配置