.NetCore技术研究-ConfigurationManager在单元测试下的坑

2023-11-18

最近在将原有代码迁移.NET Core, 代码的迁移基本很快,当然也遇到了不少坑,重构了不少,后续逐步总结分享给大家。今天总结分享一下ConfigurationManager遇到的一个问题。

先说一下场景:

   迁移.NET Core后,已有的配置文件,我们希望做到兼容,比如说app.config和web.config,

   这样配置文件尽可能地和.NET Framework是一套,尽可能低保持一致。比如:appSettings自定义configSection等等。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="CustomConfigs" type="ClassLibraryNetStandard.CustomConfigHandler, ClassLibraryNetStandard"/>
  </configSections>
  <CustomConfigs>
    <CustomConfig name="service1" order="0" reflectconfig="ClassLibraryNetStandard.TestService, ClassLibraryNetStandard"/>
    <CustomConfig name="service2" order="1" reflectconfig="ClassLibraryNetStandard.TestService2, ClassLibraryNetStandard"/>
  </CustomConfigs>  
  <appSettings>
    <add key="service" value="service1"/>
  </appSettings>
</configuration>

 对于上面配置读取我们做了以下几个事情

   1. 添加Nuget:System.Configuration.ConfigurationManager

   2. 保证原有自定义Section配置相关的代码、读取配置的代码,迁移到.NET Core后编译通过

   3. 修改配置文件、单元测试

 一、添加Nuget:System.Configuration.ConfigurationManager

   搜索System.Configuration.ConfigurationManager:找到Nuget包,并添加引用:

   

二、保证原有自定义Section配置相关的代码、读取配置的代码,迁移到.NET Core后编译通过

  示例代码中,自定义配置类CustomConfig

using System;
using System.Collections.Generic;
using System.Text;

namespace ClassLibraryNetStandard
{
    public class CustomConfig
    {
        public string Name { get; set; }

        public string ReflectConfig { get; set; }

        public int Order { get; set; }
    }
}

  同时对应的Section配置节解析类:CustomConfigHandler,实现接口:System.Configuration.IConfigurationSectionHandler

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace ClassLibraryNetStandard
{
   public class CustomConfigHandler : System.Configuration.IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, XmlNode section)
        {
            var configs = new List<CustomConfig>();

            //获取配置文件中自定义节点值  
            foreach (XmlNode childNode in section.ChildNodes)
            {
                string name = null;
                var config = new CustomConfig();
                if (childNode.Attributes["name"] != null)
                {
                    name = childNode.Attributes["name"].Value;
                    config.Name = name;

                    if (childNode.Attributes["order"] != null)
                    {
                        config.Order = Convert.ToInt32(childNode.Attributes["order"].Value);
                    }
                    if (childNode.Attributes["reflectconfig"] != null)
                    {
                        config.ReflectConfig = childNode.Attributes["reflectconfig"].Value;
                    }                  

                    configs.Add(config);
                }
            }

            return configs;
        }
    }
}

    同时,我们编写了一个简单的配置管理类:CustomConfigManager,其中有配置读取方法,直接读取配置文件:

        public static List<CustomConfig> GetCustomConfigs()
        {
            var sectionConfig = System.Configuration.ConfigurationManager.GetSection("CustomConfigs");
            if (sectionConfig != null)
            {
                return  sectionConfig as List<CustomConfig>;
            }

            return null;
        }

  

  这里我们使用了.NET Standard 2.0 library project,代码编译通过:

1>------ 已启动全部重新生成: 项目: ClassLibraryNetStandard, 配置: Debug Any CPU ------
1>C:\Program Files\dotnet\sdk\3.0.100-preview3-010431\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(151,5): message NETSDK1057: 你正在使用 .NET Core 的预览版。请查看 https://aka.ms/dotnet-core-preview
1>ClassLibraryNetStandard -> C:\Users\***\source\repos\NETFrameworkTest\ClassLibraryNetStandard\bin\Debug\netstandard2.0\ClassLibraryNetStandard.dll
========== 全部重新生成: 成功 1 个,失败 0 个,跳过 0 个 ==========

   三、修改配置文件、单元测试

  添加MSTest单元测试工程:   

  

   增加App.config配置文件:

   

   在单元测试方法中测试配置的读取:

       [TestMethod]
        public void ConfigTest()
        {
            var configs = ClassLibraryNetStandard.CustomConfigManager.GetCustomConfigs();
            Assert.IsNotNull(configs);
        }

  原本以为,肯定可以获取到配置,实际获取的configs是null。

        换了个Console类的应用,同样的配置文件读取,一点没有问题:

      

      对比看了一下这两个工程,发现除了实际编译生成的配置文件名称不同,其他都一样。

      问题肯定出在了单元测试工程上。Google了一下:有以下发现:       

MSTest is running as testhost.dll, which means that ConfigurationManager is reading settings from testhost.dll.config when executing under .NET core. 
It will look for testhost.dll.config where the testhost.dll is located as the accepted answer states.
What is not mentioned is that it will also look for testhost.dll.config in the location where you have your test dlls.

  一句话:MSTest以testhost.dll运行,去取的配置文件是testhost.dll.config

        这太尴尬了,直接无语,不过有两个解决方案:

        1. 直接在单元测试工程中将app.config文件改为:testhost.dll.config

        2. 修改单元测试工程文件,配置编译后事件,动态copy生成testhost.dll.config

       

      试过之后,果真可以了,问题解决,分享给大家。

 

 

周国庆

2019/9/12

转载于:https://www.cnblogs.com/tianqing/p/11514840.html

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

.NetCore技术研究-ConfigurationManager在单元测试下的坑 的相关文章

  • 为什么通过派生类对基类的引用与 :: - 运算符不明确?

    所以我想知道为什么以下钻石问题的代码片段无法编译 我知道这个问题通常是通过虚拟继承来解决的 我不是故意使用它的 该代码只是为了展示我的问题 即为什么编译器称此不明确 因此 我在 struct Base 中声明了两个成员变量 因为这两个子类
  • 编写此代码片段的有效方法是什么? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 更有效和 或更短地重写此代码以节省字节并显得不那么冗长的方法 if N 2 0 N 6 N 8 N 10 N 12 N 14 N 16 N
  • WebClient.DownloadDataAsync 冻结了我的 UI

    我在 Form 构造函数中的 InitializeComponent 之后有以下代码 using WebClient client new WebClient client DownloadDataCompleted new Downloa
  • 是否可以从 C++ 应用程序调用 C# 应用程序?

    我是一名编程学生 现在我已经上了两门 C 课程 这个学期我将参加我的第一门 C 课程 出于好奇 是否可以从 C 应用程序调用 C 应用程序 如果是的话 是否还可以检查运行该程序的计算机是否具有 NET框架 我只是很好奇 我想如果可能的话 这
  • 锁定 ASP.NET 应用程序变量

    我在 ASP NET 应用程序中使用第三方 Web 服务 对第 3 方 Web 服务的调用必须同步 但 ASP NET 显然是多线程的 并且可能会发出多个页面请求 从而导致对第 3 方 Web 服务的同时调用 对 Web 服务的调用封装在自
  • 司机和提供商之间的区别

    数据库中的驱动程序和提供程序有什么区别 有没有解释一下 不胜感激 样本 ADO NET driver for MySQL vs providerName System Data EntityClient 来自 MSDN 论坛 驱动程序是安装
  • C# 处理标准输入

    我目前正在尝试通过命令行断开与网络文件夹的连接 并使用以下代码 System Diagnostics Process process2 new System Diagnostics Process System Diagnostics Pr
  • 将下拉列表与字典绑定

    我将字典绑定到下拉列表 举例来说 我的字典中有以下项目 Test1 123 Test2 321 我希望下拉文本采用以下格式 Test1 Count 123 Test2 Count 321 我沿着以下路径走 但没有运气 MyDropDown
  • C 中“complex”的默认类型

    根据我读过的文档 C99 和更高版本的支持float complex double complex and long double complex作为复杂类型 但是 此代码在使用时编译时不会发出警告gcc Wall Wextra inclu
  • 全局使用和 .NET Standard 2.0

    我最近意识到我可以使用 C 10 功能文件范围的命名空间在 NET Standard 2 0 项目中也可以通过设置
  • C++ 将联合强制转换为其成员类型之一

    以下对我来说似乎完全符合逻辑 但不是有效的 C 联合不能隐式转换为其成员类型之一 有人知道为什么不这样做的充分理由吗 union u int i char c function f int i int main u v v i 6 f v
  • 带有运算符语法的错误消息,但不带有函数语法的错误消息

    为什么我在调用 unary 时收到错误消息 使用运算符语法 如果我用函数语法调用它就可以了 现场演示 https godbolt org z j7AbeQ template
  • 如何在win32中使用GetSaveFileName保存文件?

    我编写此代码是为了获取 fileName 来保存我的文件 include stdafx h include
  • Resharper:IEnumerable 的可能多重枚举

    我正在使用新的 Resharper 版本 6 在我的代码中的几个地方 它给一些文本加了下划线 并警告我可能存在IEnumerable 可能的多重枚举 我理解这意味着什么 并在适当的情况下采纳了建议 但在某些情况下 我不确定这实际上是一个大问
  • 如何在 C# 中获取 Json 数组?

    我有一个像这样的 Json 字符串 我想将它加载到 C 数组中 当我尝试这样做时 我收到异常 我的字符串 customerInformation customerId 123 CustomerName Age 39 Gender Male
  • 使用 OleDbCommandBuilder 时访问 SQL 语法错误

    我要在 C 中使用 OleDbDataAdapter 在 Access 数据库中插入数据 但收到错误消息INSERT INTO 命令中的语法错误 BackgroundWorker worker new BackgroundWorker Ol
  • 将错误代码映射到 C++ 中的字符串

    将错误代码从枚举映射到字符串的更有效方法是什么 在 C 中 例如 现在我正在做这样的事情 std string ErrorCodeToString enum errorCode switch errorCode case ERROR ONE
  • C++ 到 C# 事件处理

    所以我有我的C WinForm 应用程序 我从中调用我的C CLI MFC dll图书馆 但也有一些events在我的 C 库上 甚至此事件也发生在该库的本机 非 CLI 部分 我需要从我的 C 应用程序调用一些代码 并获取一些有关此事件的
  • 从 NumPy 数组到 Mat 的 C++ 转换 (OpenCV)

    我正在围绕 ArUco 增强现实库 基于 OpenCV 编写一个薄包装器 我试图构建的界面非常简单 Python 将图像传递给 C 代码 C 代码检测标记并将其位置和其他信息作为字典元组返回给 Python 但是 我不知道如何在 Pytho
  • SQL Server“未找到网络路径”在不同环境中随机且不频繁地发生

    类似 如果不是同一个问题 随机遇到网络路径未找到异常 https stackoverflow com questions 38696448 network path not found exception encountered rando

随机推荐

  • 内存的堆分配和栈分配 & 字符数组,字符指针,Sizeof总结

    程序占用的内存分为几个部分 各个部分起什么作用 字符数组 字符指针在实现上有什么区别等等 本文对此做了详细阐述 特转载于此 供大家学习参考之用 一个由C C 编译的程序占用的内存分为以下几个部分 1 栈区 stack 由编译器自动分配释放
  • 数据驱动性能体验优化

    本专题共10篇内容 包含淘宝APP基础链路过去一年在用户体验数据科学领域 包括商详 物流 性能 消息 客服 旅程等 一些探索和实践经验 在商详页基于用户动线和VOC挖掘用户决策因子带来浏览体验提升 在物流侧洞察用户求助时间与实际物流停滞时长
  • Ceph Pool操作总结

    Ceph Pool操作总结 一个ceph集群可以有多个pool 每个pool是逻辑上的隔离单位 不同的pool可以有完全不一样的数据处理方式 比如Replica Size 副本数 Placement Groups CRUSH Rules 快
  • bazel的使用

    bazel的使用 bazel是google开源的构建工具 可以支持多种语言的构建 这里来尝试一下如何在C 项目中使用bazel构建 安装就不介绍了 在官网很详细 输入bazel help Usage bazel
  • AD中如何对圆形PCB板进行铺铜

    因为之前做了一块圆形的PCB板子 所以在铺铜时候发现圆形铺铜我该怎么快速去铺 于是查了一下网上 大部分人是推荐先圈出一个圆弧 然后在通过快捷键TVG或者是按下 shift 空格 但是我发现不适合我 于是我分享一下自己的方法 我们如果要对圆形
  • 调参小技巧-DBSCAN参数选取方法

    利用循环迭代一些参数变量选取最适合的参数 1 初始数据处理部分 请自行对照调整 此处仅作为保持流程完整使用 读入第三方包 from sklearn import preprocessing 选取建模的变量 predictors Birth
  • 不得不引起足够重视的anonymous用户!

    连日的阴雨 使原本炎热的天气突然变得潮湿起来 烦躁的心情也慢慢地平复了下来 像往常一下 借用CuteFtp工具登录自己的VPS 检查一下文件异常 突然之间 几个刺眼的 exe文件呈现在我的眼前 顿时惊出我一身冷汗 下意识到 网站被黑客入侵了
  • C#使用Npgsql或SqlClient连接数据库

    目录 SqlClient连接SQL Server 安装SqlClient SqlConnection SqlCommand SqlConnection 和 SqlCommand的区别 Npgsql连接PostgreSQL 安装Npgsql
  • Asp.net core

    Startup类 以配置应用所需的服务 应用的请求处理管道定义为一系列中间件组件 public class Startup public void ConfigureServices IServiceCollection services
  • prototype.js 和json.js 冲突

    1 冲突简述和分析 prototype js与json js并不是完全兼容的 主要冲突在于json js为Object的原型增加了一个toJSONString的方法 冲突之一 是prototype中发送ajax请求时 遍历了一个header
  • 微众银行发布区块链“善度”,提出区块链优化社会治理参考框架

    2019年9月17日 以 区块链新经济 新十年 新起点 为主题的第五届区块链全球峰会在上海召开 微众银行副行长兼首席信息官马智涛受邀发表演讲 在峰会主论坛上 微众银行正式发布区块链优化社会治理模式参考框架 善度 为区块链行业发展提出新的发展
  • (Linux) ----> Centos7.X+配置MySQL(亲测,详细步骤)

    目录 一 创建虚拟机 1 1 新建虚拟机 编辑 1 2 虚拟机配置 二 使用外部工具连接服务器操作 XShell MobaXterm1 CHS1 根据自己习惯选择 2 1 设置Ip地址 编辑 2 2 连接虚拟机 三 下载相关的压缩包并配置连
  • VQGAN(Vector Quantized Generative Adversarial Network)模型简介

    论文 Taming Transformers for High Resolution Image Synthesis VQGAN Vector Quantized Generative Adversarial Network 是一种基于 G
  • Rocky Linux 9.1 新手入门指南

    文章目录 安装系统 配置网络 NetworkManager 配置 默认 ipaddress 配置文件 nmtui 配置 ipaddress nmcli 配置 ipaddress 网络管理 网关配置 检查网络连接 配置 bond 设置主机名
  • cmd怎么实现隐藏DOS窗口运行程序

    写个xxx vbs调用执行aaa bat即可 CreateObject WScript Shell Run cmd c aaa bat 0
  • spring gateway 的搭建与配置

    步骤 建项目 给主启动类添加Eureka的注解 EnableEurekaClient 添加并配置application yml 第一步 新建gateway的项目 gateway 8205 需要用到的组件
  • el-descriptions的使用

    el descriptions的使用 解释 我们页面有很多无序的列表展示 为了高效得去开发我们得页面 可以借助于这个组件进行适应 图片 代码 template部分
  • MIPI D-PHY介绍(二) FPGA

    MIPI D PHY介绍 二 FPGA 随着移动设备的广泛普及 MIPI D PHY作为其最主要的物理层标准之一 被越来越多地使用在各种嵌入式系统中 本文将详细介绍MIPI D PHY的工作原理和在FPGA设计中的实现方法 MIPI D P
  • 在k8s集群内搭建Prometheus监控平台

    基本架构 Prometheus由SoundCloud发布 是一套由go语言开发的开源的监控 报警 时间序列数据库的组合 Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态 任意组件只要提供对应的HTTP接口就可以接入
  • .NetCore技术研究-ConfigurationManager在单元测试下的坑

    最近在将原有代码迁移 NET Core 代码的迁移基本很快 当然也遇到了不少坑 重构了不少 后续逐步总结分享给大家 今天总结分享一下ConfigurationManager遇到的一个问题 先说一下场景 迁移 NET Core后 已有的配置文