码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2019-10-01 09:44:07      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:eid   code   attribute   value   代码   namespace   一个   研究   key   

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

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

先说一下场景:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
2
3
4
5
6
7
8
9
10
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配置文件:

   技术图片

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

1
2
3
4
5
6
[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

       技术图片

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

 

 

周国庆

2019/9/12

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

标签:eid   code   attribute   value   代码   namespace   一个   研究   key   

原文地址:https://www.cnblogs.com/lonelyxmas/p/11614508.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!