visual the studio net installed instalar framework following connectionstrings cannot alongside agregar c# .net-4.0 configuration-files

c# - the - net versions



¿Cómo tener atributo personalizado en ConfigurationElementCollection? (4)

Esto puede ser un poco tarde pero puede ser útil para otros.

Es posible pero con alguna modificación.

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

  • Por lo general, cuando ConfigurationElementCollection se hereda y se implementa en otra clase, "this [string]" se oculta con "new this [string]".

  • Una forma de evitarlo es crear otra implementación de este [] como "este [string, string]"

Vea el ejemplo a continuación.

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

para la configuración de la siguiente manera

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

cuando implemento un MyCollection, ¿qué debo hacer para el atributo "predeterminado"?


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

Supongo que tienes que implementar esto por ti mismo. 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, en su código, accede al elemento predeterminado utilizando lo 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 de Repositories y CurrentRepository. Puede tener una propiedad llamada DefaultRepository (de tipo Repository) en la clase MyConfig para devolver esto.


Si quieres genérico, 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); } } }

Aquí está la interfaz mencionada anteriormente:

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


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>

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

Puedes leer la configuración con el atributo ''predeterminado'', como este:

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

Esto dará salida a "uno"