2012-01-12 3 views
25

для конфигурации следующегоКак получить настраиваемый атрибут в ConfigurationElementCollection?

<MyCollection default="one"> 
    <entry name="one" ... other attrubutes /> 
    ... other entries 
</MyCollection> 

при реализации MyCollection, что я должен сделать для «по умолчанию» атрибут?

+0

проверить это: https://stackoverflow.com/questions/43037691/design-to-implement-a-wrapper-for-configurationsection-net-class –

ответ

49

Давайте предположим, что у вас есть этот .config файл:

<configuration> 
    <configSections> 
     <section name="mySection" type="ConsoleApplication1.MySection, ConsoleApplication1" /> // update type & assembly names accordingly 
    </configSections> 

    <mySection> 
     <MyCollection default="one"> 
      <entry name="one" /> 
      <entry name="two" /> 
     </MyCollection> 
    </mySection> 
</configuration> 

Затем, с помощью этого кода:

public class MySection : ConfigurationSection 
{ 
    [ConfigurationProperty("MyCollection", Options = ConfigurationPropertyOptions.IsRequired)] 
    public MyCollection MyCollection 
    { 
     get 
     { 
      return (MyCollection)this["MyCollection"]; 
     } 
    } 
} 

[ConfigurationCollection(typeof(EntryElement), AddItemName = "entry", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class MyCollection : ConfigurationElementCollection 
{ 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new EntryElement(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     if (element == null) 
      throw new ArgumentNullException("element"); 

     return ((EntryElement)element).Name; 
    } 

    [ConfigurationProperty("default", IsRequired = false)] 
    public string Default 
    { 
     get 
     { 
      return (string)base["default"]; 
     } 
    } 
} 

public class EntryElement : ConfigurationElement 
{ 
    [ConfigurationProperty("name", IsRequired = true, IsKey = true)] 
    public string Name 
    { 
     get 
     { 
      return (string)base["name"]; 
     } 
    } 
} 

вы можете прочитать конфигурацию с атрибутом 'по умолчанию', как это:

MySection section = (MySection)ConfigurationManager.GetSection("mySection"); 
    Console.WriteLine(section.MyCollection.Default); 

Это будет выдавать «один»

+1

AddItemName = "запись", это именно то, что Я хочу! – Xinan

5

Я не знаю, возможно ли иметь значение по умолчанию в ConfigurationElementCollection. (он не имеет никакого свойства для значения по умолчанию).

Я думаю, вы должны реализовать это самостоятельно. Посмотрите пример ниже.

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

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

public class RepositoryCollection : ConfigurationElementCollection 
{ 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new Repository(); 
    } 

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

    public Repository this[int index] 
    { 
     get { return base.BaseGet(index) as Repository; } 
    } 

    public new Repository this[string key] 
    { 
     get { return base.BaseGet(key) as Repository; } 
    } 

} 

public class MyConfig : ConfigurationSection 
{ 
    [ConfigurationProperty("currentRepository", IsRequired = true)] 
    private string InternalCurrentRepository 
    { 
     get { return (string)this["currentRepository"]; } 
    } 

    [ConfigurationProperty("repositories", IsRequired = true)] 
    private RepositoryCollection InternalRepositories 
    { 
     get { return this["repositories"] as RepositoryCollection; } 
    } 
} 

Вот XML конфигурации:

<myConfig currentRepository="SQL2008"> 
    <repositories> 
     <add key="SQL2008" value="abc"/> 
     <add key="Oracle" value="xyz"/> 
    </repositories> 
    </myConfig> 

И затем, в вашем коде, вы получаете доступ пункт по умолчанию, используя следующие:

MyConfig conf = (MyConfig)ConfigurationManager.GetSection("myConfig"); 
string myValue = conf.Repositories[conf.CurrentRepository].Value; 

Конечно, класс MyConfig может скрыть сведения о доступе к свойствам репозиториев и CurrentRepository. У вас может быть свойство DefaultRepository (типа Repository) в классе MyConfig, чтобы вернуть его.

0

Если вы хотите genericize его, это должно помочь:

using System.Configuration; 

namespace Abcd 
{ 
    // Generic implementation of ConfigurationElementCollection. 
    [ConfigurationCollection(typeof(ConfigurationElement))] 
    public class ConfigurationElementCollection<T> : ConfigurationElementCollection 
             where T : ConfigurationElement, IConfigurationElement, new() 
    { 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return new T(); 
    } 

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

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

    public T GetElement(object key) 
    { 
     return (T)BaseGet(key); 
    } 
    } 
} 

Вот интерфейс ссылки выше:

namespace Abcd 
{ 
    public interface IConfigurationElement 
    { 
    object GetElementKey(); 
    } 
} 
1

Это может быть немного поздно, но может быть полезным для других.

Возможно, но с некоторой модификацией.

  • КонфигурацияElementCollection наследует ConfigurationElement как таковую «эта [строка]» доступна в ConfigurationElement.

  • Обычно, когда ConfigurationElementCollection наследуется и реализуется в другом классе, «эта [строка]» скрыта с «new this [string]».

  • Один из способов обойти это заключается в создании другой реализации этого [], такие как «это [строка, строка]»

пример ниже.

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

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

    public CustomElement this[int index] 
    { 
     get { return (CustomElement)base.BaseGet(index); } 
     set 
     { 
      if (BaseGet(index) != null) 
       BaseRemoveAt(index); 

      BaseAdd(index, value); 
     } 
    } 

    // ConfigurationElement this[string] now becomes hidden in child class 
    public new CustomElement this[string name] 
    { 
     get { return (CustomElement)BaseGet(name); } 
    } 

    // ConfigurationElement this[string] is now exposed 
    // however, a value must be entered in second argument for property to be access 
    // otherwise "this[string]" will be called and a CustomElement returned instead 
    public object this[string name, string str = null] 
    { 
     get { return base[name]; } 
     set { base[name] = value; } 
    } 
} 
Смежные вопросы