2010-04-23 8 views
14

C'è un modo per me di includere una semplice matrice di stringhe o una stringa < nella stringa > nella sottoclasse personalizzata di ConfigurationSection? (O un array o un elenco generico di oggetti dati semplici, per quello?)Come includere raccolte semplici in ConfigurationSection

Sto acquisendo familiarità con le nuove (e MOLTO verbose) classi ConfigurationSection, ConfigurationElement e ConfigurationElementCollection, ma non sono affatto un esperto ancora.

Sembra che ConfigurationSection debba gestire raccolte/elenchi semplici da solo, senza che io debba creare una sottoclasse ConfigurationElementCollection personalizzata per ognuno. Ma non ho trovato alcun riferimento a questa capacità online.

Modifica: accettare la risposta di Dan come risposta, poiché è probabilmente la cosa più vicina che otterrò alle "configSections" vecchio stile. Ho sempre trovato facile, flessibile ed elegante che qualsiasi oggetto XmlSerializable potesse facilmente diventare una configSection. Sono sicuro che il nuovo framework è più potente; tuttavia è triste che sia così ingombrante per semplici contrasti di configurazione, che siamo ridotti a tornare a String.Split().

risposta

8

OK, hai chiesto di essere semplice. Bene, il modo più semplice per memorizzare una serie di stringhe consiste nell'utilizzare un elenco delimitato (ad esempio, separato da virgole). In questo modo è possibile memorizzarlo in un solo elemento (ad esempio in appSettings).

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

Naturalmente, questo ha degli svantaggi ma nella maggior parte dei casi funziona bene per un elenco semplice. È quindi possibile utilizzare String.Split() per riconvertirlo in un array/elenco.

Altrimenti si ritorna agli elementi ConfigurationSection che, concordo, sono molto prolissi e goffi con cui lavorare. Ma non so in nessun altro modo, temo (ma sono contento di essere smentito!).

+0

Dan D - grazie, ma hai ragione, non ero alla ricerca di qualcosa di così semplice! :) Ho usato liste delimitate e String.Split prima, e sono sicuro che lo userò di nuovo. Ma speravo in qualcosa di un po 'più elegante. Forse qualcun altro risponderà con qualcosa che abbiamo perso. – mikemanne

+0

Non pensavo così, ma a volte gli sviluppatori ignorano l'ovvio. È nella nostra natura! –

19

Ecco un semplice esempio.

//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 per il file di configurazione:

<?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

Grazie per la risposta, soprattutto per una domanda relativamente vecchia. :) Purtroppo, non è ancora quello che sto cercando. Hai una matrice di oggetti di 1a classe, ognuno contenente un paio di stringhe. Tutto ciò che voglio è una serie di stringhe. Usando le sezioni di configurazione "vecchio stile", sono riuscito a farlo senza creare un oggetto personalizzato. Speravo che ci fosse un modo per farlo all'interno del nuovo framework di configurazione, senza la necessità di creare un oggetto per includere essenzialmente un elenco . – mikemanne

+0

L'ho usato. Mi ha salvato un sacco di tempo. Un tweak: public static readonly stringa MAPPINGS_CONFIGURATION_SECTION_NAME = "TransformationToDirectoryMappingsSection"; dovrebbe essere public cost string MAPPINGS_CONFIGURATION_SECTION_NAME = "TransformationToDirectoryMappingsSection"; –

+0

Il premio per le minuzie a occhio d'aquila va a __JDN_____! Ah ah, mi hai preso. L'ho cambiato. Sono contento che ci abbia aiutato. – granadaCoder

10

Impostazioni applicazione Architettura

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

Ok, un vecchio post, ma mi sono ricordato che quando mi sono imbattuto in un situazione simile:

...

Se si passa a Progetto/Proprietà progetto (in VS2008 o VS2010). C'è una scheda "Impostazioni".

Se si aggiunge un nuovo valore ....

Uno dei tipi si chiama: System.Collections.Specialized.StringCollection

dargli un nome (io ho usato "FavoriteColors").

Impostare il tipo (come indicato sopra).

Impostare il/i valore/i.

"String Collection Editor" dice "Immettere le stringhe nella raccolta (una per riga)".

sono entrato:

Red

Giallo

nero

Bianco

Questo aggiungerà un po 'di XML al file 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> 

(Sarete meglio andare con i punti, piuttosto che incollare il codice XML di cui sopra, in quanto (per concisione) non ho aggiunto tutto il xml a questo post che viene generato.

Si dovrebbe essere in grado di "arrivare a" i valori tramite codice come questo:

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

nota, la procedura descritta sopra produrrà il sotto codice C# (codice auto creato per voi .... è non codice creato) ma l'aspetto del codice s come questo:

 [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

grazie per la risposta - questo è davvero un vecchio post! In realtà non sono più nel progetto che l'ha ispirato. :) All'epoca in cui ho scritto questa domanda, ero consapevole della tecnica che descrivevi qui, quindi deve esserci stato un motivo per cui non l'ho usato. Ma per la vita di me non riesco a ricordare perché. Quando avrò la possibilità, ci giocherò un po 'di più, e segnerò il tuo post sulla risposta, o fornirò maggiori informazioni sul perché non soddisfa i miei bisogni. Grazie ancora! – mikemanne

+0

Oops - ho appena capito che ho già segnato una risposta a questo, e non voglio revocarlo. Ma sicuramente altererò la tua risposta. :) – mikemanne

2

So che la questione è stata risolta molto tempo fa ... ma in classi miei 'ConfigurationElement', per la raccolta di stringa, di solito faccio la seguente:

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

e si può ottenere un elenco di stringhe da questa proprietà con

List<string> myStrings = config.MyStringCollectionProperty.Cast<string>.ToList() 
Problemi correlati