我可以将 app.config 个自定义部分解析为 List 数据结构吗?

Can I parse app.config custom sections to List data structure?

我有以下 app.config 自定义部分:

<myCustomSection>
    <person1 name = "John" age = "30">
    <person2 name = "Mike" age = "46">
</muCustomSection>

下面的代码在 System.Configuration.ConfigurationManager 的帮助下解析它:

public class MyCustomCongifuration : ConfigurationSection {
     [ConfigurationProperty("person1", IsRequired = true)]
     public PersonConfiguration Person1
     {
         get => (PersonConfiguration)this["person1"];
         set => this["person1"] = value;
     }

     [ConfigurationProperty("person2", IsRequired = true)]
     public PersonConfiguration Person2
     {
         get => (PersonConfiguration)this["person2"];
         set => this["person2"] = value;
     }
}

我想重构代码以使用以下 app.config:

<myCustomSection>
    <person name = "John" age = "30">
    <person name = "Mike" age = "46">
</muCustomSection>

我希望在 MyCustomConfiguration 对象中获得 PersonConfiguration 列表:

var configuration = ConfigurationManager.GetSection("myCustomSection") as MyCustomConfiguration;
var persons = configuration.Persons; // returns List<PersonConfiguration>

这可能吗?我该怎么做?

我不确定您如何使用 ConfigurationManager 做到这一点,但另一种方法可能是使用 XML Linq:

using System.Xml.Linq;

XDocument doc = XDocument.Load("C:\path\to\file.config");
var persons = doc.Element("configuration").Element("myCustomSection").Descendants("person");

foreach (var person in persons)
{
    var Name = Attribute("name").Value;
    var Age = Attribute("age").Value;
}

您可以使用以下方法删除项目:

doc.Element("configuration").Elements("myCustomSection").First(s =>(string)s.Attribute("name") == "Name you want to find").Remove();

.NET Framework 确实支持在其配置中包含项目列表,但并不像您列出的那样。如果您查看文件的 appSettings 部分,您可以看到一个集合示例:

<appSettings>
  <add key="foo" value="Fizz" />
  <add key="bar" value="Buzz" />
</appSettings>

这是建立在专门的集合 ConfigurationElementCollection 之上的,它允许您将 add removeclear 函数建模为 XML 以便构建你的物品清单。

首先,将PersonConfigurationname属性标记为key。我假设这个人的名字适合作为关键标识符;如果您想出不同的标识符,请使用它。

[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
{
    get { return (string)this["name"]; }
    set { this["name"] = value; }
}

创建源自 ConfigurationElementCollection 的自定义集合,这样您就可以 return 一个人的关键值。

[ConfigurationCollection(typeof(PersonConfiguration))]
public class PersonConfigurationElementCollection : ConfigurationElementCollection
{
    protected override PersonConfiguration CreateNewElement()
    {
        return new PersonConfiguration();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((PersonConfiguration)element).Name;
    }
}

然后将此集合添加到您的自定义配置部分的 class:

public class MyCustomCongifuration : ConfigurationSection
{
     [ConfigurationProperty("people", IsDefaultCollection = true)]
     public PersonConfigurationElementCollection People
     {
         get { return (PersonConfigurationElementCollection)this["people"]; }
         set { this["people"] = value; }
     }
}

您现在可以这样创建人物集合:

<myCustomSection>
  <people>
    <add name="John" age="30" />
    <add name="Mike" age="46" />
  </people>
</muCustomSection>

如果你想将该配置集合变成一个列表,你可以使用一点 Linq:

var configuration = (MyCustomConfiguration)ConfigurationManager
    .GetSection("myCustomSection");
var people = configuration.People.Cast<PersonConfiguration>().ToList();