代码之家  ›  专栏  ›  技术社区  ›  Johnny

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

  •  0
  • Johnny  · 技术社区  · 15 年前

    我想实施 Craig Andera's custom XML configuration handler 在稍微不同的情况下。我希望能够在自定义对象的任意长度列表中读取,定义为:

    public class TextFileInfo
    {
        public string Name { get; set; }
        public string TextFilePath { get; set; }
        public string XmlFilePath { get; set; }
    }
    

    我成功地为一个自定义对象复制了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));
        }
    }
    

    我想如果我能

    Type t = Type.GetType("System.Collections.Generic.List<TextFileInfo>")
    

    去工作,但它会抛出

    Could not load type 'System.Collections.Generic.List<Test1.TextFileInfo>' from assembly 'Test1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
    
    1 回复  |  直到 15 年前
        1
  •  5
  •   Matthew Abbott    15 年前

    我认为在那种情况下,这是行不通的。Craig的解决方案对于简单的对象图很好地工作,但是集合有点棘手。列表被序列化为数组,因此将示例放入序列化列表中,类似于:

    <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>
    

    现在,我猜你可以把它放到一个配置中,只要配置部分被命名为“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;
      }
    }
    

    注册配置部分后:

    <configSections>
      <add name="textFiles" type="...{type here}..." />
    </configSections>
    

    您可以添加配置:

    <textFiles>
      <files>
        <add name="File01" textFilePath="C:\File01.txt" xmlTextFile="C:\File01.xml" />
      </files>
    </textFiles>
    

    在代码中使用它:

    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;
    }
    

    此外,这一点:

    Type t = Type.GetType("System.Collections.Generic.List<TextFileInfo>")
    

    不会工作的原因有两个,你还没有完全限定textfileinfo类型(需要一个名称空间),你对一个泛型类型的定义是错误的(我可以理解为什么你没有这样指定),它应该是:

    Type t = Type.GetType("System.Collections.Generic.List`1[MyNamespace.TextFileInfo]");
    

    希望有帮助!