.NetCore技术研究-ConfigurationManager在单元测试下的坑
最近在將原有代碼遷移.NET Core, 代碼的遷移基本很快,當然也遇到了不少坑,重構了不少,后續逐步總結分享給大家。今天總結分享一下ConfigurationManager遇到的一個問題。
先說一下場景:
? ?遷移.NET Core后,已有的配置文件,我們希望做到兼容,比如說app.config和web.config,
? ?這樣配置文件盡可能地和.NET Framework是一套,盡可能低保持一致。比如:appSettings、自定義configSection等等。
<?xml?version="1.0" encoding="utf-8" ?> <configuration> ??<configSections> ????<<strong>section</strong> name="CustomConfigs" type="ClassLibraryNetStandard.CustomConfigHandler, ClassLibraryNetStandard"/> ??</configSections> ??<<strong>CustomConfigs</strong>> ????<CustomConfig?name="service1" order="0" reflectconfig="ClassLibraryNetStandard.TestService, ClassLibraryNetStandard"/> ????<CustomConfig?name="service2" order="1" reflectconfig="ClassLibraryNetStandard.TestService2, ClassLibraryNetStandard"/> ??</CustomConfigs>? ??<<strong>appSettings</strong>> ????<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,其中有配置讀取方法,直接讀取配置文件:
1 | 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了一下:有以下發現:? ? ? ?
1 | MSTest is running as testhost.dll, which means that ConfigurationManager is reading settings from testhost.dll.config when executing under .NET core. <br>It will look for testhost.dll.config where the testhost.dll is located as the accepted answer states. <br>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
? ? ? ?
? ? ? 試過之后,果真可以了,問題解決,分享個大家。
原文鏈接:https://www.cnblogs.com/tianqing/p/11514840.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?
總結
以上是生活随笔為你收集整理的.NetCore技术研究-ConfigurationManager在单元测试下的坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core 3.0 可卸载程序集
- 下一篇: dotNET Core实现分布式环境下的