2011-05-09 2 views
1

Je veux le meilleur des deux mondes: Je veux être en mesure de maintenir les changements pendant l'exécution, comme les paramètres de l'application portée par l'utilisateur, et je veux aussi que ces paramètres soient globaux. Existe-t-il un moyen d'accomplir cela via les fichiers de paramètres app.config? Dois-je regarder d'une autre façon de persister des paramètres modifiables d'exécution globaux pour mon application?Paramètres de configuration modifiables globaux dans C# .NET?

Répondre

0

Ok, voici comment je l'ai résolu:

Je crée ConfigurationSection vraiment de base, ConfigurationElement et ConfigurationElementCollection implémentations:

public class CoreConfigurationSection : ConfigurationSection 
{ 
    [ConfigurationProperty("settings", IsDefaultCollection = true)] 
    [ConfigurationCollection(typeof(CoreSettingCollection), AddItemName = "setting")] 
    public CoreSettingCollection Settings 
    { 
     get 
     { 
      return (CoreSettingCollection)base["settings"]; 
     } 
    } 
} 

public class CoreSetting : ConfigurationElement 
{ 
    public CoreSetting() { } 

    public CoreSetting(string name, string value) 
    { 
     Name = name; 
     Value = value; 
    } 

    [ConfigurationProperty("name", IsRequired = true, IsKey = true)] 
    public string Name 
    { 
     get { return (string)this["name"]; } 
     set { this["name"] = value; } 
    } 

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

public class CoreSettingCollection : ConfigurationElementCollection 
{ 
    public new string this[string name] 
    { 
     get { return BaseGet(name) == null ? string.Empty : ((CoreSetting)BaseGet(name)).Value; } 
     set { Remove(name); Add(name, value); } 
    } 

    public void Add(string name, string value) 
    { 
     if (!string.IsNullOrEmpty(value)) 
      BaseAdd(new CoreSetting(name, value)); 
    } 

    public void Remove(string name) 
    { 
     if (BaseGet(name) != null) 
      BaseRemove(name); 
    } 

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

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

Et puis une classe gérer le fichier de configuration:

public static class Settings 
{ 
    private static string _root { get { return "core"; } } 

    private static Configuration Load() 
    { 
     string filename = Path.Combine(Core.BaseDirectory, "core.config"); 

     var mapping = new ExeConfigurationFileMap {ExeConfigFilename = filename}; 
     var config = ConfigurationManager.OpenMappedExeConfiguration(mapping, ConfigurationUserLevel.None); 

     var section = (CoreConfigurationSection)config.GetSection(_root); 

     if (section == null) 
     { 
      Console.Write("Core: Building core.config..."); 

      section = new CoreConfigurationSection(); 
      config.Sections.Add(_root, section); 
      Defaults(section); 
      config.Save(ConfigurationSaveMode.Modified); 

      Console.WriteLine("done"); 
     } 

     return config; 
    } 

    private static void Defaults(CoreConfigurationSection section) 
    { 
     section.Settings["Production"] = "false"; 
     section.Settings["Debug"] = "false"; 
     section.Settings["EventBot"] = "true"; 
     section.Settings["WebAccounting"] = "true"; 
     section.Settings["AllowPlayers"] = "true"; 
    } 

    #region Accessors 

    public static string Get(string setting) 
    { 
     var config = Load(); 
     var section = (CoreConfigurationSection)config.GetSection(_root); 

     return section.Settings[setting]; 
    } 

    public static bool GetBoolean(string setting) 
    { 
     var config = Load(); 
     var section = (CoreConfigurationSection)config.GetSection(_root); 

     return section.Settings[setting].ToLower() == "true"; 
    } 

    public static void Set(string setting,string value) 
    { 
     var config = Load(); 
     var section = (CoreConfigurationSection)config.GetSection(_root); 

     if (value == null) 
      section.Settings.Remove(setting); 

     section.Settings[setting] = value; 
     config.Save(ConfigurationSaveMode.Modified); 
    } 

    public static void SetBoolean(string setting, bool value) 
    { 
     var config = Load(); 
     var section = (CoreConfigurationSection)config.GetSection(_root); 

     section.Settings[setting] = value.ToString(); 
     config.Save(ConfigurationSaveMode.Modified); 
    } 

    #endregion 

    #region Named settings 

    public static bool Production 
    { 
     get { return GetBoolean("Production"); } 
     set { SetBoolean("Production", value); } 
    } 

    public static bool Debug 
    { 
     get { return GetBoolean("Debug"); } 
     set { SetBoolean("Debug", value); } 
    } 

    public static bool EventBot 
    { 
     get { return GetBoolean("EventBot"); } 
     set { SetBoolean("EventBot", value); } 
    } 

    public static bool WebAccounting 
    { 
     get { return GetBoolean("WebAccounting"); } 
     set { SetBoolean("WebAccounting", value); } 
    } 

    public static bool AllowPlayers 
    { 
     get { return GetBoolean("AllowPlayers"); } 
     set { SetBoolean("AllowPlayers", value); } 
    } 

    #endregion 
} 

Je ne pouvais pas vraiment penser à une meilleure façon de faire des configurations typées que de les coder en dur, mais à part ça me semble assez solide, vous pouvez créer et mettre à jour des configurations à l'exécution, elles sont globales, modifiables ma racine d'application, donc en gros cela couvre toutes les fonctionnalités que je voulais. Le fichier core.config est créé à l'exécution s'il n'existe pas, il est vérifié chaque fois que vous essayez de charger ou d'enregistrer un paramètre, avec des valeurs par défaut juste pour "commencer" ... (vous pouvez ignorer) que "initialisation" bien.

Le fichier core.config ressemble à ceci

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
     <section name="core" type="Server.CoreConfigurationSection, ServerCore, Version=2.1.4146.38077, Culture=neutral, PublicKeyToken=null" /> 
    </configSections> 
    <core> 
     <settings> 
      <setting name="Production" value="false" /> 
      <setting name="Debug" value="false" /> 
      <setting name="EventBot" value="true" /> 
      <setting name="WebAccounting" value="true" /> 
      <setting name="AllowPlayers" value="true" /> 
     </settings> 
    </core> 
</configuration> 
1

Le gestionnaire de configuration intégré dans .Net qui est utilisé pour gérer les paramètres de l'application dans les fichiers de configuration est en lecture seule donc techniquement, vous ne pouvez pas le faire en utilisant les bibliothèques intégrées, cependant le fichier de configuration est juste xml , donc il n'y a aucune raison pour laquelle vous ne pouvez pas simplement mettre à jour le fichier de configuration en utilisant les méthodes standard xml, puis appelez

ConfigurationManager.RefreshSection("appSettings") 

lorsque vous voulez recharger vos paramètres

0

de plus, la OpenMappedExeConfiguration() de la ConfigurationManager vous permet de charger dynamiquement un fichier de configuration de votre choix (à condition qu'il suive le schéma .NET xml config) et demandez à votre application de charger les options de configuration, ainsi vous pouvez modifier le fichier comme @lomax indiqué et avez un fichier commun que vous pouvez charger de toutes vos applications, en utilisant la même méthode.

Voici quelques informations sur OpenMappedExeConfiguration

Questions connexes