你的位置:首页 > ASP.net教程

[ASP.net教程].NET Core采用的全新配置系统[9]: 为什么针对XML的支持不够好?如何改进?


物理文件是我们最常用到的原始配置的载体,最佳的配置文件格式主要由三种,它们分别是JSON、

一、为什么针对集合的配置难以通过优雅的

在《配置模型设计详解》一文中我们对配置模型的设计和实现进行了详细介绍。在此文中我们说应用中的配置体现为一种树形化的层次结构,所我将它称为“配置树”,具体的配置数据通过配置树的“叶子节点”承载。当配置数据从不同的来源加载之后都会转换成一个字典,我将其称为“配置字典”。为了让“配置字典”能够存储“配置树”的所有数据和自身结构,我们需要在配置字典中存储所有叶子节点,叶子节点的路径和值将直接作为字典元素的Key和Value。由于字典的Key是唯一的,这就要求配置树中的每一个节点必须具有唯一的路径。

  1: public class Profile
  2: {
  3:   public Gender     Gender { get; set; }
  4:   public int      Age { get; set; }
  5:   public ContactInfo  ContactInfo { get; set; }
  6: }
  7:  
  8: public class ContactInfo
  9: {
 10:   public string EmailAddress { get; set; }
 11:   public string PhoneNo { get; set; }
 12: }
 13:  
 14: public enum Gender
 15: {
 16:   Male,
 17:   Female
 18: }


举个简单的例子,假设需要采用

  1: <Profiles>
  2:  <Profile Gender="Male" Age="18">
  3:   <ContactInfo EmailAddress ="foobar@outlook.com" PhoneNo="123"/>
  4:  </Profile>
  5:  <Profile Gender="Male" Age="25">
  6:   <ContactInfo EmailAddress ="bar@outlook.com" PhoneNo="456"/>
  7:  </Profile>
  8:  <Profile Gender="Male" Age="40">
  9:   <ContactInfo EmailAddress ="baz@outlook.com" PhoneNo="789"/>
 10: </Profile>


对于这段

image

二、按照配置树的要求对

之所以

我们通过派生

12

如上图所示,针对集合对原始

  1: public class Extended
  2: {
  3:  public Extendedbase(source)
  4:   {}
  5:  
  6:   public override void Load(Stream stream)
  7:   {
  8:     //加载源文件并创建一个
  9:     new 
 10:     sourceDoc.Load(stream);
 11:  
 12:     //添加索引
 13:     this.AddIndexes(sourceDoc.DocumentElement);
 14:  
 15:     //根据添加的索引创建一个新的
 16:     new 
 17:     
 18:     newDoc.AppendChild(documentElement);
 19:  
 20:     foreach (in sourceDoc.DocumentElement.ChildNodes)
 21:     {
 22:       this.Rebuild(element, documentElement, 
 23:         name => newDoc.CreateElement(name));
 24:     }
 25:  
 26:     //根据新的
 27:     using (Stream newStream = new MemoryStream())
 28:     {
 29:       using (
 30:       {
 31:         newDoc.WriteTo(writer);
 32:       }
 33:       newStream.Position = 0;
 34:       base.Load(newStream);
 35:     }
 36:   }
 37:  
 38:   private void AddIndexes(
 39:   {
 40:     if (element.ChildNodes.OfType<
 41:     {
 42:       if (element.ChildNodes.OfType<
 43:       {
 44:         int index = 0;
 45:         foreach (in element.ChildNodes)
 46:         {
 47:           subElement.SetAttribute("append_index", (index++).ToString());
 48:           AddIndexes(subElement);
 49:         }
 50:       }
 51:     }
 52:   }
 53:  
 54:   private void Rebuild(string, 
 55:   {
 56:     string index = source.GetAttribute("append_index");
 57:     string elementName = string.IsNullOrEmpty(index) ? source.Name : $"{source.Name}_index_{index}";
 58:     
 59:     destParent.AppendChild(element);
 60:     foreach (in source.Attributes)
 61:     {
 62:       if (attribute.Name != "append_index")
 63:       {
 64:         element.SetAttribute(attribute.Name, attribute.Value);
 65:       }
 66:     }
 67:  
 68:     foreach (in source.ChildNodes)
 69:     {
 70:       Rebuild(subElement, element, creator);
 71:     }
 72:   }
 73: }