Изменить значение дочернего элемента пользовательского раздела конфигурации
Я пытаюсь удалить старые устаревшие ссылки и сейчас работаю над тем, что мне никогда не приходилось делать раньше. Допустим, у меня есть раздел с конфигурационным файлом:
<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;
}
}