2010-04-23 8 views
14

¿Hay alguna manera de incluir una matriz simple de cadenas o la cadena de > en mi subclase personalizada de ConfigurationSection? (O una matriz o lista genérica de objetos de datos simples, para el caso)Cómo incluir colecciones simples en ConfigurationSection

Me estoy familiarizando con las nuevas (y muy detalladas) clases ConfigurationSelement, ConfigurationElement y ConfigurationElementCollection, pero de ninguna manera soy experto todavía.

Parece que ConfigurationSection debe manejar colecciones simples/listas por sí mismo, sin que yo tenga que crear una subclase personalizada ConfigurationElementCollection para todas y cada una. Pero no he encontrado ninguna referencia a esta habilidad en línea.

Edición: aceptando la respuesta de Dan como la respuesta, ya que es probablemente lo más cercano que voy a llegar a las configuraciones de "estilo antiguo". Siempre me pareció fácil, flexible y elegante que cualquier objeto XmlSerializable pudiera convertirse fácilmente en una sección de configuración. Estoy seguro de que el nuevo marco es más poderoso; Sin embargo, es triste que sea TAN engorroso para las configuraciones simples, que estamos reducidos a volver a String.Split().

Respuesta

8

Bien, usted lo pidió simple. Bueno, la forma más sencilla de almacenar una serie de cadenas sería usar una lista delimitada (por ejemplo, separada por comas). De esta forma, puede almacenarlo en un solo elemento (por ejemplo, en la configuración de la aplicación).

<add key="weekDays" value="Monday,Tuesday,Wednesday,Thursday,Friday"/> 

Por supuesto, esto tiene inconvenientes, pero en la mayoría de los casos funciona bien para una lista simple. A continuación, puede usar String.Split() para convertirlo a una matriz/lista.

De lo contrario, volverá a los elementos de ConfigurationSection que, estoy de acuerdo, son muy detallados y torpes para trabajar. Pero no sé de ninguna otra manera, me temo (¡pero estoy feliz de que se demuestre que estoy equivocado!).

+0

Dan D - gracias, pero tiene razón, ¡no estaba buscando algo así de simple! :) He usado listas delimitadas y String.Split antes, y estoy seguro de que volveré a usarlo. Pero esperaba algo un poco más elegante. Tal vez alguien más responderá con algo que nos hemos perdido. – mikemanne

+0

No lo creo, pero a veces los desarrolladores pasan por alto lo obvio. ¡Está en nuestra naturaleza! –

19

Aquí hay un ejemplo simple.

//START CODE 


//MyCompany.MyProject.csproj which results in MyCompany.MyProject.dll 
//Add a Folder called "Configuration" 

namespace MyCompany.MyProject.Configuration 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 

    using System.Configuration; 


    public class TransformationToDirectoryMapping : ConfigurationElement 
    { 

     private const string FRIENDLY_NAME = "FriendlyName"; 
     private const string PICKUP_FOLDER = "PickupFolder"; 

     [ConfigurationProperty(FRIENDLY_NAME, DefaultValue = "", IsKey = false, IsRequired = true)] 
     public string FriendlyName 
     { 
      get 
      { 
       return ((string)(base[FRIENDLY_NAME])); 
      } 
      set 
      { 
       base[FRIENDLY_NAME] = value; 
      } 
     } 

     [ConfigurationProperty(PICKUP_FOLDER, DefaultValue = "", IsKey = true, IsRequired = true)] 
     public string PickupFolder 
     { 
      get 
      { 
       return ((string)(base[PICKUP_FOLDER])); 
      } 
      set 
      { 
       base[PICKUP_FOLDER] = value; 
      } 
     } 



    } 

    //----------------------------------------------------------------------- 

    //----------------------------------------------------------------------- 

    [ConfigurationCollection(typeof(TransformationToDirectoryMapping))] 
    public class TransformationToDirectoryMappingCollection : ConfigurationElementCollection 
    { 

     protected override ConfigurationElement CreateNewElement() 
     { 
      return new TransformationToDirectoryMapping(); 
     } 

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


     public TransformationToDirectoryMapping this[int idx] 
     { 
      get 
      { 
       return (TransformationToDirectoryMapping)BaseGet(idx); 
      } 
     } 

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

    //----------------------------------------------------------------------- 

    //----------------------------------------------------------------------- 

    public class TransformationToDirectoryMappingConfigSection : ConfigurationSection 
    { 
     private const string TRANSFORMATION_TO_DIRECTORY_MAPPINGS = "TransformationToDirectoryMappings"; 

     [ConfigurationProperty(TRANSFORMATION_TO_DIRECTORY_MAPPINGS)] 
     public TransformationToDirectoryMappingCollection TransformationToDirectoryMappingItems 
     { 
      get { return ((TransformationToDirectoryMappingCollection)(base[TRANSFORMATION_TO_DIRECTORY_MAPPINGS])); } 
     } 
    } 

    //----------------------------------------------------------------------- 

    //----------------------------------------------------------------------- 

    public static class MyRetriever 
    { 
     public const string MAPPINGS_CONFIGURATION_SECTION_NAME = "TransformationToDirectoryMappingsSection"; 

     public static TransformationToDirectoryMappingCollection GetTheCollection() 
     { 
      TransformationToDirectoryMappingConfigSection mappingsSection = (TransformationToDirectoryMappingConfigSection)ConfigurationManager.GetSection(MAPPINGS_CONFIGURATION_SECTION_NAME); 
      if (mappingsSection != null) 
      { 
       return mappingsSection.TransformationToDirectoryMappingItems; 
      } 
      return null; // OOPS! 

     } 
    } 

} 

// XML para el archivo de configuración:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <section name="TransformationToDirectoryMappingsSection" type="MyCompany.MyProject.Configuration.TransformationToDirectoryMappingConfigSection, MyCompany.MyProject"/> 
    </configSections> 

    <TransformationToDirectoryMappingsSection> 
    <TransformationToDirectoryMappings> 
     <add FriendlyName="Hello" PickupFolder="C:\WUWUTemp\pickups\pickup11\" /> 
     <add FriendlyName="GoodBye" PickupFolder="C:\WUWUTemp\pickups\pickup12\" /> 
    </TransformationToDirectoryMappings> 
    </TransformationToDirectoryMappingsSection> 
</configuration> 
+0

Gracias por la respuesta, especialmente a una pregunta relativamente antigua. :) Lamentablemente, todavía no es exactamente lo que estoy buscando. Tienes una variedad de objetos de primera clase, cada uno con un par de cuerdas. Todo lo que quiero es una variedad de cadenas. Utilizando secciones de configuración "antiguas", pude hacerlo sin crear un objeto personalizado. Esperaba que hubiera una manera de hacerlo dentro del nuevo marco de configuración, sin necesidad de crear un objeto para envolver esencialmente una lista . – mikemanne

+0

Lo usé. Me ahorró mucho tiempo. Un ajuste: cadena de solo lectura pública estática MAPPINGS_CONFIGURATION_SECTION_NAME = "TransformationToDirectoryMappingsSection"; debe ser una cadena pública const MAPPINGS_CONFIGURATION_SECTION_NAME = "TransformationToDirectoryMappingsSection"; –

+0

¡El premio de las minucias de ojo de águila va para __JDN_____! Ja, ja, me tienes. Lo cambie. Me alegro de que haya ayudado. – granadaCoder

10

Configuración de la aplicación Arquitectura

http://msdn.microsoft.com/en-us/library/8eyb2ct1.aspx

Ok, un antiguo puesto, pero lo recordaba cuando me encontré con una situación similar:

...

Si va a Project/Project Properties (en VS2008 o VS2010). Hay una pestaña "Configuración".

Si se agrega un nuevo valor ....

Uno de los tipos se llama: System.Collections.Specialized.StringCollection

darle un nombre (he usado "FavoriteColors").

Establezca el tipo (como se indicó anteriormente).

Establezca el valor (es).

El "Editor de String Collection" dice "Introduzca las cadenas en la colección (una por línea)".

entré:

Rojo

amarillo

Negro

blanca

Se añadirán xml para su archivo app.config.

<setting name="FavoriteColors" serializeAs="Xml"> 
     <value> 
      <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
       <string>red</string> 
       <string>yellow</string> 
       <string>black</string> 
       <string>white</string> 
      </ArrayOfString> 
     </value> 
    </setting> 

(Usted será mejor ir a través de los pasos en lugar de pegar el código XML anterior, debido a que (Por razones de concisión) no añadí todo el xml para este puesto que se genera.

Usted debe ser capaz de "llegar a" los valores a través de un código como éste:

private void ShowMyFavoriteColors() 
{ 
      Properties.Settings.Default.FavoriteColors.Cast<string>().ToList().ForEach(myfavcolor => 
      { 
       string temp = myfavcolor; 
      }); 
} 

Nota, los pasos anteriores producen el siguiente código C# (código auto creado para ti .... es no código se crea) pero el código se ve s como este:

 [global::System.Configuration.ApplicationScopedSettingAttribute()] 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
     [global::System.Configuration.DefaultSettingValueAttribute(@"<?xml version=""1.0"" encoding=""utf-16""?> 
<ArrayOfString xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> 
    <string>red</string> 
    <string>yellow</string> 
    <string>black</string> 
    <string>white</string> 
</ArrayOfString>")] 
     public global::System.Collections.Specialized.StringCollection FavoriteColors { 
      get { 
       return ((global::System.Collections.Specialized.StringCollection)(this["FavoriteColors"])); 
      } 
     } 
    } 
} 
+0

gracias por la respuesta - ¡esta es de hecho una publicación anterior! En realidad, ya no estoy en el proyecto que lo inspiró. :) En el momento en que escribí esta pregunta, estaba al tanto de la técnica que describe aquí, por lo que debe haber alguna razón por la que no la utilicé. Pero por mi vida no puedo recordar por qué. Cuando tenga la oportunidad, jugaré con eso un poco más, y marcaré tu publicación como respuesta o proporcionaré más información sobre por qué no se ajusta a mis necesidades. ¡Gracias de nuevo! – mikemanne

+0

Vaya, me acabo de dar cuenta de que ya marqué una respuesta a esto, y no quiero revocarla. Pero definitivamente voy a votar mejor tu respuesta. :) – mikemanne

2

Sé que la pregunta ha sido contestada hace mucho tiempo ... pero en mis clases 'ConfigurationElement', para la recolección de la cadena, que suele hacer lo siguiente:

[ConfigurationProperty("myStringCollectionProperty", DefaultValue = "")] 
[TypeConverter(typeof(CommaDelimitedStringCollectionConverter))] 
public StringCollection MyStringCollectionProperty 
{ 
    get { return (StringCollection)this["myStringCollectionProperty"]; } 
    set { this["myStringCollectionProperty"] = value; } 
} 

Y puede obtener una lista de cuerdas de esta propiedad con

List<string> myStrings = config.MyStringCollectionProperty.Cast<string>.ToList() 
Cuestiones relacionadas