Изменить значение дочернего элемента пользовательского раздела конфигурации

Я пытаюсь удалить старые устаревшие ссылки и сейчас работаю над тем, что мне никогда не приходилось делать раньше. Допустим, у меня есть раздел с конфигурационным файлом:

<customSection>
    <customValues>
      <custom key="foo" invert="True">
         <value>100</value>
      </custom>
      <custom key="bar" invert="False">
         <value>200</value>
      </custom>
    </customValues>
</customSection>

Теперь я создал классы ConfigurationSection, ConfigurationElement и ConfigurationElementCollection, чтобы правильно прочитать все это. Вот они для справки (это в основном вся базовая схема, за исключением класса ValueElement, который переопределяет метод Deserialize для получения значения элемента):

public class CustomSection : ConfigurationSection
{
    [ConfigurationProperty("customValues")]
    [ConfigurationCollection(typeof(CustomValueCollection), AddItemName = "custom")]
    public CustomValueCollection CustomValues
    {
        get { return (CustomValueCollection)this["customValues"]; }
    }
}

public class CustomValueCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new CustomElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((CustomElement) element).Key;
    }

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

    new public CustomElement this[string key]
    {
        get { return (CustomElement) BaseGet(key); }
    }

    public bool ContainsKey(string key)
    {
        var keys = new List<object>(BaseGetAllKeys());
        return keys.Contains(key);
    }
}

public class CustomElement : ConfigurationElement
{
    [ConfigurationProperty("key", IsRequired = true)]
    public string Key
    {
        get { return (string)this["key"]; }
    }

    [ConfigurationProperty("invert", IsRequired = true)]
    public bool Invert
    {
        get { return (bool)this["invert"]; }
    }

    [ConfigurationProperty("value", IsRequired = true)]
    public ValueElement Value
    {
        get { return (ValueElement)this["value"]; }
    }
}

public class ValueElement : ConfigurationElement
{
    private int value;

    //used to get value of element, not of an attribute
    protected override void DeserializeElement(System.Xml.XmlReader reader, bool serializeCollectionKey)
    {
        value = (int)reader.ReadElementContentAs(typeof(int), null);
    }

    public int Value
    {
        get { return value; }
    }
}

Теперь я застрял в этом бизнес-требовании: если CustomElement имеет значение Invert, равное true, то инвертирует значение свойства Value в связанном ValueElement. Так что, если бы я получил доступ к значению "value" в "foo", я бы получил -100.

Кто-нибудь знает, как передать что-то подобное объекту ValueElement или сделать так, чтобы ValueElement знал о своем родительском CustomElement, чтобы иметь возможность получить это свойство Invert? Моя первоначальная мысль - выполнить проверку в получателе свойства Value класса CustomElement, и если значение Invert равно true, тогда измените объект ValueElement, но я открыт для других идей.

Цель здесь - удалить устаревший код, не касаясь файла конфигурации, в противном случае я бы вставил подэлемент "value" в родительский элемент как атрибут.

Спасибо

1 ответ

Решение

Судя по всему, вам просто нужно изменить Value свойство get для включения вашей инвертированной логики. Я не вижу причин, почему это не сработает.

Вы можете добавить другое свойство, которое также получает необработанное значение.

[ConfigurationProperty("value", IsRequired = true)]
public int Value
{
    get 
    {
        var result = (ValueElement)this["value"]; 
        return Invert ? result.Value * -1 : result.Value;
    }
}
Другие вопросы по тегам