2012-01-12 16 views
25

para la configuración de la siguiente maneracómo tener un atributo personalizado en ConfigurationElementCollection?

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

cuando implementar un MiColeccion, lo que debería hacer por el "default" atribuir?

+0

mira esto: https://stackoverflow.com/questions/43037691/design-to-implement-a-wrapper-for-configurationsection-net-class –

Respuesta

49

Supongamos que tiene este archivo .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> 

Entonces, con este código:

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

se puede leer la configuración con el atributo 'por defecto', como este:

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

Esto generará "uno"

+1

AddItemName = "entrada", eso es exactamente lo ¡Yo quiero! – Xinan

5

No sé si es posible tener un valor predeterminado en una ConfigurationElementCollection. (no se ve que tenga ninguna propiedad para el valor predeterminado).

Supongo que tiene que implementar esto por su cuenta. Mira el ejemplo de abajo.

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

Aquí está la configuración XML:

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

Y luego, a su código, se accede a la opción por defecto utilizando la siguiente:

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

Por supuesto, la clase MyConfig puede ocultar los detalles de acceso a las propiedades Repositories y CurrentRepository. Puede tener una propiedad llamada DefaultRepository (de tipo Repository) en la clase MyConfig para devolver esto.

0

Si desea genericize ella, esto debería ayudar:

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

Esta es la unión hace referencia más arriba:

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

Esto puede ser un poco tarde, pero puede ser de utilidad para otros.

Es posible pero con algunas modificaciones.

  • ConfigurationElementCollection hereda ConfigurationElement como tal "esta [cadena]" está disponible en ConfigurationElement.

  • Normalmente, cuando ConfigurationElementCollection se hereda e implementa en otra clase, "this [string]" se oculta con "new this [string]".

  • Una manera de conseguir alrededor de él es crear otra aplicación de esta [] tales como "este [cadena, cadena]"

Consulte el siguiente ejemplo.

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