如何读取自定义配置对象列表

Joh*_*nny 0 c# configuration app-config

我想在稍微不同的场景中实现Craig Andera的自定义XML配置处理程序.我想要做的是读入任意长度的自定义对象列表,定义如下:

public class TextFileInfo
{
    public string Name { get; set; }
    public string TextFilePath { get; set; }
    public string XmlFilePath { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我设法为一个自定义对象复制了Craig的解决方案,但如果我想要几个呢?

Craig的反序列化代码是:

public class XmlSerializerSectionHandler : IConfigurationSectionHandler
{
    public object Create(object parent, object configContext, XmlNode section)
    {
        XPathNavigator nav = section.CreateNavigator();
        string typename = (string)nav.Evaluate("string(@type)");
        Type t = Type.GetType(typename);
        XmlSerializer ser = new XmlSerializer(t);
        return ser.Deserialize(new XmlNodeReader(section));
    }
}
Run Code Online (Sandbox Code Playgroud)

如果可以的话,我想我能做到这一点

Type t = Type.GetType("System.Collections.Generic.List<TextFileInfo>")
Run Code Online (Sandbox Code Playgroud)

工作,但它抛出

Could not load type 'System.Collections.Generic.List<Test1.TextFileInfo>' from assembly 'Test1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Run Code Online (Sandbox Code Playgroud)

Mat*_*ott 5

我不认为这会在那种情况下起作用.Craig的解决方案适用于简单的对象图,但集合有点棘手.列表被序列化为数组,因此将示例放入序列化List中就像:

<ArrayOfTextFileInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlsns:xsd="http://www.w3.org/2001/XMLSchema>
  <TextFileInfo>
    <Name>My Text File</Name>
    <TextFilePath>C:\MyTextFile.txt</TextFilePath>
    <XmlFilePath>C:\MyXmlFile.xml</XmlFilePath>
  </TextFileInfo>
</ArrayOfTextFileInfo>
Run Code Online (Sandbox Code Playgroud)

现在,我猜你可以将它放在配置中,只要配置部分命名为"ArrayOfTextFileInfo".不完全那么友好.我认为您应该做的是使用标准配置类来构建它:

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

  [ConfigurationProperty("textFilePath")]
  public string TextFilePath {
    get { return (string)this["textFilePath"]; }
    set { this["textFilePath"] = value; }
  }

  [ConfigurationProperty("xmlFilePath")]
  public string XmlFilePath {
    get { return (string)this["xmlFilePath"]; }
    set { this["xmlFilePath"] = value; }
  }
}

[ConfigurationCollection(typeof(TextFileConfigurationElement))]
public class TextFileConfigurationElementCollection : ConfigurationElementCollection
{
  protected override void CreateNewElement() {
    return new TextFileConfigurationElement();
  }

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

public class TextFilesConfigurationSection : ConfigurationSection
{
  [ConfigurationProperty("files")]
  public TextFileConfigurationElementCollection Files {
    get { return (TextFileConfigurationElementCollection)this["files"]; }
    set { this["files"] = value; }
  }

  public static TextFilesConfigurationSection GetInstance() {
    return ConfigurationManager.GetSection("textFiles") as TextFilesConfigurationSection;
  }
}
Run Code Online (Sandbox Code Playgroud)

一旦注册了配置部分:

<configSections>
  <add name="textFiles" type="...{type here}..." />
</configSections>
Run Code Online (Sandbox Code Playgroud)

您可以添加配置:

<textFiles>
  <files>
    <add name="File01" textFilePath="C:\File01.txt" xmlTextFile="C:\File01.xml" />
  </files>
</textFiles>
Run Code Online (Sandbox Code Playgroud)

在代码中使用它:

public List<TextFileInfo> GetFiles() {
  var list = new List<TextFileInfo>();

  var config = TextFileConfigurationSection.GetInstance();
  if (config == null)
    return list;

  foreach (TextFileConfigurationElement fileConfig in config.Files) {
    list.Add(new TextFileInfo 
                        {
                          Name = fileConfig.Name,
                          TextFilePath = fileConfig.TextFilePath,
                          XmlFilePath = fileConfig.XmlFilePath
                         });

  }

  return list;
}
Run Code Online (Sandbox Code Playgroud)

这个:

Type t = Type.GetType("System.Collections.Generic.List<TextFileInfo>")
Run Code Online (Sandbox Code Playgroud)

由于几个原因无法工作,你没有完全限定TextFileInfo类型(需要一个命名空间),你的泛型类型的定义是错误的(我可以看到为什么你没有这样指定),它应该是这样的:

Type t = Type.GetType("System.Collections.Generic.List`1[MyNamespace.TextFileInfo]");
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!