如何从 ASP.Net Core 配置文件合并多个数组?

2024-02-21

我想在我的应用程序中动态加载和注册服务。为此,我需要能够从解决方案中的不同项目加载配置文件,并将它们的值合并到单个 json 数组中。 不幸的是,默认情况下,ASP.Net Core 配置会覆盖值。

我使用以下代码注册文件(Program.cs 文件的一部分):

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((webHostBuilderContext, configurationbuilder) =>
            {
                var env = webHostBuilderContext.HostingEnvironment;
                configurationbuilder.SetBasePath(env.ContentRootPath);
                configurationbuilder.AddJsonFile("appsettings.json", false, true);

                var path = Path.Combine(env.ContentRootPath, "App_Config\\Include");

                foreach(var file in Directory.EnumerateFiles(path, "*.json",SearchOption.AllDirectories))
                {
                    configurationbuilder.AddJsonFile(file, false, true);
                }
                configurationbuilder.AddEnvironmentVariables();
            })
            .UseStartup<Startup>();

该代码搜索所有文件*.json内部延伸App_Config\Include目录并将它们全部添加到配置生成器中。

文件的结构如下所示:

{
  "ServicesConfiguration": {
    "Services": [
      {
        "AssemblyName": "ParsingEngine.ServicesConfigurator, ParsingEngine"
      }
    ]
  }
}

正如你所看到的,我有主要部分ServicesConfiguration then Services包含具有一个属性的对象的数组AssemblyName.

为了读取我使用的这些值ServicesConfiguration带有列表的类:

public class ServicesConfiguration
    {
        public List<ServiceAssembly> Services { get; set; }
    }

该列表使用ServiceAssembly class:

public class ServiceAssembly
    {
        public string AssemblyName { get; set; }
    }

为了加载我使用的配置IOptions在构造函数级别 (DI):

Microsoft.Extensions.Options.IOptions<ServicesConfiguration> servicesConfiguration,

配置似乎已加载 - 但文件中的值不会合并,而是被最后找到的文件覆盖。

有什么想法如何解决这个问题吗?


所以你知道我在评论中的意思,这是一个潜在的答案

由于您必须从不同的项目加载不同的“配置”文件并对它们应用一些合并逻辑,因此我会避免使用“默认”配置系统来加载JSON文件到应用程序中。相反,我会自己做。所以:

  1. 读取 JSON 并将其反序列化为类型并将其保留在列表中
  2. 浏览包含所有配置的列表并应用您的合并逻辑
  3. 注册单号ServicesConfiguration as a Singleton
  4. 删除您的代码Program.cs加载自定义JSON files

您可以这样做:

ServicesRootConfiguration(新类,能够反序列化json)

public class ServicesRootConfiguration
{
    public ServicesConfiguration ServicesConfiguration { get; set; }
}

Startup.cs

public class Startup
{
    private readonly IHostingEnvironment _hostingEnvironment;

    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        Configuration = configuration;
        _hostingEnvironment = env;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // other configuration omitted for brevity

        // build your custom configuration from json files
        var myCustomConfig = BuildCustomConfiguration(_hostingEnvironment);

        // Register the configuration as a Singleton
        services.AddSingleton(myCustomConfig);
    }

    private static ServicesConfiguration BuildCustomConfiguration(IHostingEnvironment env)
    {
        var allConfigs = new List<ServicesRootConfiguration>();

        var path = Path.Combine(env.ContentRootPath, "App_Config");

        foreach (var file in Directory.EnumerateFiles(path, "*.json", SearchOption.AllDirectories))
        {
            var config = JsonConvert.DeserializeObject<ServicesRootConfiguration>(File.ReadAllText(file));
            allConfigs.Add(config);
        }

        // do your logic to "merge" the each config into a single ServicesConfiguration
        // here I simply select the AssemblyName from all files.
        var mergedConfig = new ServicesConfiguration
        {
            Services = allConfigs.SelectMany(c => c.ServicesConfiguration.Services).ToList()
        };

        return mergedConfig;
    }
}

然后在你的Controller通常只需通过 DI 获取实例即可。

public class HomeController : Controller
{
    private readonly ServicesConfiguration _config;

    public HomeController(ServicesConfiguration config)
    {
        _config = config ?? throw new ArgumentNullException(nameof(config));
    }
}

通过这种方法,您最终会获得与正常注册相同的行为IOptions。但是,您可以避免依赖它并不得不使用丑陋的.Value(呃)。更好的是,您可以将其注册为接口,以便在测试/模拟期间使您的生活更轻松。

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

如何从 ASP.Net Core 配置文件合并多个数组? 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile

随机推荐