Search code examples
c#configurationsectionno-duplicates

c# ConfigurationSection not returning duplicate names


I have a configuration section reading from a config file. The xml looks like this

<GroupBySection>
    <Groups>
        <Group name="Source" product="Product One">
            <Items>
                <Item name="2003" type="radio" />
                <Item name="2007" type="radio" />
                <Item name="2010" type="radio" />
                <Item name="2013" type="radio" />
                <Item name="o365" type="radio" />
            </Items>
        </Group>
        <Group name="Target" product="Product One">
            <Items>
                <Item name="2003" type="radio" />
                <Item name="2007" type="radio" />
                <Item name="2010" type="radio" />
                <Item name="2013" type="radio" />
                <Item name="o365" type="radio" />
            </Items>
        </Group>
        <Group name="Source" product="Product Two">
            <Items>
                <Item name="2003" type="radio" />
                <Item name="2007" type="radio" />
                <Item name="2010" type="radio" />
                <Item name="2013" type="radio" />
                <Item name="o365" type="radio" />
            </Items>
        </Group>
    </Groups>
</GroupBySection>

When I call this configuration section and do a count I am only seeing the first Product One results. Product Two does not display and It is because the name is also "Source". I want it to display all them regardless if the name is the same. So in short it wont return anything with the same name it has already come across even though I want it to. Could anyone point out what ive done wrong?

Code below

ConfigurationSection

public class GroupByConfiguration : ConfigurationSection
{
    [ConfigurationProperty("Groups")]
    public GroupByElementCollection Groups
    {
        get { return ((GroupByElementCollection)(base["Groups"])); }
        set { base["Groups"] = value; }
    }
}

Element Section

public class GroupByElement : ConfigurationElement
{
    // Group Attributes
    [ConfigurationProperty("name", IsRequired = true)]
    public string Name
    {
        get { return (string)base["name"]; }
    }

    [ConfigurationProperty("product", IsRequired = true)]
    public string Product
    {
        get { return (string)base["product"]; }
    }

    [ConfigurationProperty("Items")]
    public ItemElementCollection Items
    {
        get { return ((ItemElementCollection)(base["Items"])); }
        set { base["Items"] = value; }
    }
}

Element Collection

[ConfigurationCollection(typeof(GroupByElement))]
public class GroupByElementCollection : ConfigurationElementCollection
{
    internal const string PropertyName = "Group";

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

    protected override string ElementName
    {
        get
        {
            return PropertyName;
        }
    }

    protected override bool IsElementName(string elementName)
    {
        return elementName.Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase);
    }

    public override bool IsReadOnly()
    {
        return false;
    }

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

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

    public GroupByElement this[int idx]
    {
        get { return (GroupByElement)BaseGet(idx); }
    }

}

I am confident it is something stupid :) Thanks in advance!


Solution

  • Kind of an educated guess, but it seems like the method:

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

    is the most likely culprit. Specifically, according to this page:

    http://msdn.microsoft.com/en-us/library/system.configuration.configurationelementcollection.getelementkey(v=vs.110).aspx

    Gets the element key for a specified configuration element when overridden in a derived class.

    In other words, that method returns the means by which .NET can identify the tag in a config file in a subfolder which can override the parent's tag. It seems reasonable, in that regard, to restrict keys to be unique, so by specifying the ((GroupByElement)(element)).Name property as the key, you are saying it must be unique.

    One way around this is probably to return the Name and Product, another would be to return the Name and index within the collection, if that's possible. Yet another way, if you did not care about override behaviors, is to just return a unique Guid every time.