【问题标题】:Is there a way to read configuration sections without knowing the name of the sections? (And some more) [duplicate]有没有办法在不知道部分名称的情况下读取配置部分? (还有更多)[重复]
【发布时间】:2021-10-03 02:09:56
【问题描述】:

我正在使用一个程序,它需要处理一些所谓的“接口”。程序不知道这些“接口”的名称,但程序需要能够读取配置文件中提供的接口名称、字段的名称和值。

为了做到这一点,我创建了一个“App.config”文件,如下所示:

<configuration>
    <configSections>
        <sectionGroup name="interfaces">
            <section name="IF1" type="System.Configuration.AppSettingsSection"/>
            <section name="IF2" type="System.Configuration.AppSettingsSection"/>
            <section name="IF3" type="System.Configuration.AppSettingsSection"/>
        </sectionGroup>
    </configSections>
    <interfaces>
        <IF1>
            <add key="IF1.ENABLE" value="false"/>
        </IF1>
        <IF2>
            <add key="IF2.ENABLE" value="true"/>
            <add key="IF2.ENABLE_EVENTS" value="true"/>
            <add key="IF2.MAX" value="1000"/>
            <add key="IF2.MIN" value="100"/>
        </IF2>
        ...

但是,为了读取配置文件中的信息,我使用了以下代码(有相应的问题):

NameValueCollection settings = ConfigurationManager.GetSection("interfaces")   as NameValueCollection;
  // returns "null"
NameValueCollection settings = ConfigurationManager.GetSection("interfaces/*") as NameValueCollection;
  // returns "null"
NameValueCollection settings = ConfigurationManager.GetSection("interfaces/IF1") as NameValueCollection;
  // works OK, but it means that the name of the interface needs to be known by the application.

在观察窗口中检查settings(从最后一行开始)时,我发现这是使用Add watch 查看第一个条目的值的方式(请不要笑):

new System.Collections.ArrayList.ArrayListDebugView(
  ((System.Collections.Specialized.NameObjectCollectionBase.NameObjectEntry)
   (new System.Collections.Hashtable.HashtableDebugView(settings._entriesTable).Items[0]).Value).Value).Items[0]

尝试查看这不起作用,原因很简单,settings._entriesTable 是私有的,因此无法访问。

有没有人知道一个简单的说法:(伪代码)

foreach (entry) in configuration.interfaces
{
  foreach (interface_entry) in configuration.interfaces.getSection(entry.name)
  {
    string keyname   = interface_entry.key;
    string valuename = interface_entry.value;
  }
}

还是我的配置文件格式完全错误?

【问题讨论】:

    标签: c# app-config configurationmanager


    【解决方案1】:

    我尝试使用this proposed duplicate 中的代码,但我需要做一些修改:

    private static List<string> GetNames(ConfigurationSectionGroup configSectionGroup)
    {
        var names = new List<string>();
        foreach (ConfigurationSectionGroup csg in configSectionGroup.SectionGroups)
            names.AddRange(GetNames(csg));
    
        foreach (ConfigurationSection cs in configSectionGroup.Sections)
            if (configSectionGroup.SectionGroupName == "interfaces")
            names.Add(cs.SectionInformation.SectionName);
    
        return names;
    }
    

    显然,原始代码返回 interfaces/interfaces/IF1 之类的条目,而我只想要 interfaces/IF1。将configSectionGroup.SectionGroupName 放在评论中可以解决这个问题。

    main函数原本包含两个部分:

    /* Section 1 */
    foreach (ConfigurationSectionGroup csg in config.SectionGroups)
      names.AddRange(GetNames(csg));
             
    /* Section 2 */
    foreach (ConfigurationSection cs in config.Sections)
      names.Add(cs.SectionInformation.SectionName);
    

    我不知道“第 2 节”究竟做了什么(它从哪里获取信息),但我已将其从代码中删除,现在它工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-17
      • 2018-07-07
      • 1970-01-01
      • 2015-02-05
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      • 2016-12-27
      相关资源
      最近更新 更多