2016-03-12 2 views
0

J'ai implémenté ma configuration de configuration personnalisée très imbriquée jusqu'à ce que je souhaite ajouter un nouvel attribut à l'une des collections d'éléments de configuration imbriqués. Voici ma config de travail:C#: La configuration personnalisée imbriquée ne fonctionne pas après l'ajout d'un nouvel attribut

<exchange name="myexchange"> 
    <queue name="myqueue"> 
    <process> 
     <sources> 
     <http url="[myUrl]/srcurl1" method="get" name="srcurl1" /> 
     <http url="[myUrl]/srcurl2" method="get" name="srcurl2" /> 
     </sources> 
     <destinations> 
     <http url="[intUrl]/someurl1" method="POST" name="someurl1" /> 
     <http url="[intUrl]/someurl2" method="POST" name="someurl2" /> 
     </destinations> 
    </process> 
    </queue> 
</exchange> 

Je suis en train d'ajouter isactive attribut à <destinations> collection d'éléments de configuration mais je reçois une exception Unrecognized attribute 'isactive'. Note that attribute names are case-sensitive.. Ce que j'essaie de faire:

<destinations isactive="true"> 
    <http url="[intUrl]/someurl1" method="POST" name="someurl1" /> 
    <http url="[intUrl]/someurl2" method="POST" name="someurl2" /> 
</destinations> 

Voici mon code de travail avant d'ajouter le nouvel attribut.

public class ProcessConfigElement : ConfigurationElement 
{ 
    [ConfigurationProperty("sources", IsDefaultCollection = false)] 
    public HttpConfigElementCollection Sources 
    { 
     get { return (HttpConfigElementCollection)base["sources"]; } 

    } 

    [ConfigurationProperty("destinations", IsDefaultCollection = false)] 
    public HttpConfigElementCollection Destinations 
    { 
     get { return (HttpConfigElementCollection)base["destinations"]; } 

    } 
} 

public class HttpConfigElementCollection : ConfigurationElementCollection, IEnumerable<HttpConfigElement> 
{ 
    public new HttpConfigElement this[string name] 
    { 
     get 
     { 
      if (IndexOf(name) < 0) return null; 

      return (HttpConfigElement)BaseGet(name); 
     } 
    } 

    public HttpConfigElement this[int index] 
    { 
     get { return (HttpConfigElement)BaseGet(index); } 
    } 

    public int IndexOf(string name) 
    { 
     name = name.ToLower(); 

     for (int idx = 0; idx < base.Count; idx++) 
     { 
      if (this[idx].Name.ToLower() == name) 
       return idx; 
     } 
     return -1; 
    } 

    public override ConfigurationElementCollectionType CollectionType 
    { 
     get { return ConfigurationElementCollectionType.BasicMap; } 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new HttpConfigElement(); 
    } 

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

    protected override string ElementName 
    { 
     get { return "http"; } 
    } 

    public new IEnumerator<HttpConfigElement> GetEnumerator() 
    { 
     return this.OfType<HttpConfigElement>().GetEnumerator(); 
    } 
} 

public class HttpConfigElement : ConfigurationElement 
{ 
    [ConfigurationProperty("url", IsRequired = true, DefaultValue = "")] 
    public string Url 
    { 
     get { return (string)this["url"]; } 
     set { this["url"] = value; } 
    } 

    [ConfigurationProperty("method", IsRequired = true, DefaultValue = "")] 
    public string Method 
    { 
     get { return (string)this["method"]; } 
     set { this["method"] = value; } 
    }   

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

Pour ajouter l'attribut 'isactive'. J'ai changé l'entrée de configuration pour: <destinations isactive="true"> et je pensais que je dois changer la classe ProcessConfigElement à utiliser la nouvelle collection:

[ConfigurationProperty("destinations", IsDefaultCollection = false)] 
public DestinationConfigElementCollection Destinations 
{ 
    get { return (DestinationConfigElementCollection)base["destinations"]; } 

} 

... et mes classes de collection et élément ressemble à:

public class DestinationConfigElementCollection : ConfigurationElementCollection, IEnumerable<DestinationConfigElement> 
{ 
    public DestinationConfigElementCollection() 
    { 
     DestinationConfigElement destinationConfigElement = (DestinationConfigElement)CreateNewElement(); 
     if (destinationConfigElement.IsActive != "") 
     { 
      Add(destinationConfigElement); 
     } 
    } 

    public override ConfigurationElementCollectionType CollectionType 
    { 
     get 
     { 
      return ConfigurationElementCollectionType.BasicMap; 
     } 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new DestinationConfigElement(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((DestinationConfigElement)element).IsActive; 
    } 

    public DestinationConfigElement this[int index] 
    { 
     get 
     { 
      return (DestinationConfigElement)BaseGet(index); 
     } 
     set 
     { 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 
      BaseAdd(index, value); 
     } 
    } 

    new public DestinationConfigElement this[string name] 
    { 
     get 
     { 
      return (DestinationConfigElement)BaseGet(name); 
     } 
    } 

    public int IndexOf(DestinationConfigElement destinationConfigElement) 
    { 
     return BaseIndexOf(destinationConfigElement); 
    } 

    public void Add(DestinationConfigElement destinationConfigElement) 
    { 
     BaseAdd(destinationConfigElement); 
    } 

    protected override void BaseAdd(ConfigurationElement element) 
    { 
     BaseAdd(element, false); 
    } 

    public void Remove(DestinationConfigElement destinationConfigElement) 
    { 
     if (BaseIndexOf(destinationConfigElement) >= 0) 
      BaseRemove(destinationConfigElement.IsActive); 
    } 

    public void RemoveAt(int index) 
    { 
     BaseRemoveAt(index); 
    } 

    public void Remove(string name) 
    { 
     BaseRemove(name); 
    } 

    public void Clear() 
    { 
     BaseClear(); 
    } 

    protected override string ElementName 
    { 
     get { return "destination"; } 
    } 

    public new IEnumerator<DestinationConfigElement> GetEnumerator() 
    { 
     return this.OfType<DestinationConfigElement>().GetEnumerator(); 
    } 
} 

public class DestinationConfigElement : ConfigurationElement 
{ 
    [ConfigurationProperty("isactive", IsRequired = false, IsKey = false, DefaultValue = "")] 
    public string IsActive 
    { 
     get { return (string)this["isactive"]; } 
     set { this["isactive"] = value; } 
    } 

    [ConfigurationProperty("https", IsDefaultCollection = false)] 
    public HttpConfigElementCollection Https 
    { 
     get { return (HttpConfigElementCollection)base["https"]; } 

    } 
} 

Cette n'a pas fonctionné. J'ai également essayé de changer la config à:

<destinations isactive="true"> 
    <https> 
     <http url="[intUrl]/someurl1" method="POST" name="someurl1" /> 
     <http url="[intUrl]/someurl2" method="POST" name="someurl2" /> 
    </https> 
</destinations> 

Répondre

0

J'ai été capable de résoudre ce problème maintenant. J'ai pensé que ce serait une bonne idée de le partager ici afin que moi ou quelqu'un puisse y revenir à l'avenir.

Le problème était dans ma classe ProcessConfigElement où j'utilisais une collection pour destinations. Changé d'utiliser l'élément fait fonctionner.

public class ProcessConfigElement : ConfigurationElement 
{ 
    [ConfigurationProperty("sources", IsDefaultCollection = false)] 
    public HttpConfigElementCollection Sources 
    { 
     get { return (HttpConfigElementCollection)base["sources"]; } 

    } 

    [ConfigurationProperty("destinations", IsDefaultCollection = false)] 
    public DestinationConfigElement Destinations 
    { 
     get { return (DestinationConfigElement)base["destinations"]; } 

    } 
} 

... aussi je lis c'est une bonne idée de structurer votre config où vous avez une collection et éléments avec. Donc, j'ai ajouté un autre niveau d'imbrication avec Endpoint avec en destinations.

public class DestinationConfigElement : ConfigurationElement 
{ 
    [ConfigurationProperty("isactive", IsRequired = false, IsKey = false, DefaultValue = "")] 
    public string IsActive 
    { 
     get { return (string)this["isactive"]; } 
     set { this["isactive"] = value; } 
    } 

    [ConfigurationProperty("endpoints", IsDefaultCollection = false)] 
    public HttpConfigElementCollection Endpoints 
    { 
     get { return (HttpConfigElementCollection)base["endpoints"]; } 

    } 
}