简体   繁体   English

C#:添加新属性后,嵌套的自定义配置不起作用

[英]C#: Nested custom config not working after adding a new attribute

I have my very nested custom configuration implementation working until I wanted to add a new attribute to one of the nested config element collection. 我一直在使用嵌套的自定义配置实现,直到我想向嵌套的config元素集合之一添加新属性。 Here is my working config: 这是我的工作配置:

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

I am trying to add isactive attribute to <destinations> config element collection but I get an exception Unrecognized attribute 'isactive'. Note that attribute names are case-sensitive. 我试图将isactive属性添加到<destinations>配置元素集合中,但出现异常Unrecognized attribute 'isactive'. Note that attribute names are case-sensitive. Unrecognized attribute 'isactive'. Note that attribute names are case-sensitive. . This what I am trying to do: 这是我想做的:

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

Here is my working code before adding the new attribute. 这是添加新属性之前的工作代码。

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

To add 'isactive' attribute. 添加“ isactive”属性。 I changed the config entry to: <destinations isactive="true"> and thought I need to change the ProcessConfigElement class to use new collection: 我将配置条目更改为: <destinations isactive="true">并认为我需要更改ProcessConfigElement类以使用新集合:

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

}

...and my collection and element classes look like: ...而我的集合和元素类如下所示:

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

    }
}

This didn't work. 这没用。 I also tried to change the config to: 我也尝试将配置更改为:

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

I was able to solve this issue now. 我现在能够解决此问题。 I thought it would be a good idea to share it here so that if I or anyone want to come back to this in future. 我认为在这里分享它是一个好主意,以便将来我或任何人想回到这里。

The issue was in my ProcessConfigElement class where I was using a collection for destinations . 问题出在我的ProcessConfigElement类中,其中我使用了destinations集合。 Changed it to use the element made it work. 对其进行了更改,以使用使它起作用的元素。

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

    }
}

... also I read it's a good idea to structure your config where you have a collection and then elements with in. So I added another level of nesting with Endpoint with in destinations . ......我也阅读它是一个好主意,你有一个集合,然后元素,其构建你的配置,所以我加入嵌套的另一个层面Endpointdestinations

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

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM