.NetCore技术研究-ConfigurationManager在单元测试下的坑
最近在将原有代码迁移.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 ------ ? ?三、修改配置文件、单元测试 ? 添加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.
一句话:MSTest以testhost.dll运行,去取的配置文件是testhost.dll.config ? ? ? ? 这太尴尬了,直接无语,不过有两个解决方案: ? ? ? ? 1.?直接在单元测试工程中将app.config文件改为:testhost.dll.config ? ? ? ? 2.?修改单元测试工程文件,配置编译后事件,动态copy生成testhost.dll.config ? ? ? ? ? ? ? 试过之后,果真可以了,问题解决,分享给大家。 ? ? 周国庆 2019/9/12 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – asp.net MVC 3中视图模型的范围
- asp.net – 配置节“system.servicemodel”无法读
- ASP.NET MVC – 使用ViewData将Json String传递给
- asp.net-mvc – 使用ASP.NET MVC 2 AsyncControl
- .net – 动态创建的控件未触发事件处理程序
- OAuth(OAuth2)ASP.NET REST Web API(自我主机 –
- asp.net – 在线.Net编码
- 我可以在Razor中使用@helper语法返回一个字符串吗
- C# 快速高效率复制对象另一种方式 表达式树
- asp.net – Kendo TabStrip:将动作渲染到MVC 4中