2009-06-12 5 views
1

J'ai cherché ici pour la réponse. Je suis désolé si cela a déjà été demandé (comme je le soupçonne).Des appels fortement typés dans web.config sans dupliquer les noms de propriétés?

Résumé: Comment puis-je avoir des appels fortement typés dans mon web.config sans dupliquer les noms de propriété?


Détails: Dans mon code, j'essaie de minimiser l'utilisation de la chaîne, et je n'aime pas définir quelque chose deux fois. En complément de ces deux wonts, ma restriction de l'utilisation d'AppSettings (et de ses chaînes) à une classe, que je référence tout au long du projet, est complétée par ces deux méthodes. La classe AppSettings expose les propriétés publiques:

12 public static string DateFormatString { 
    13  get { 
    14   return ConfigurationManager.AppSettings["DateFormatString"]; 
    15  } 
    16 } 

Comment puis-je conserver cette classe et éviter la duplication (lignes 12 & 14) du nom de la propriété?

Sinon, quelle autre solution pourriez-vous recommander?

Répondre

0

je recommanderais probablement désérialisation le web.config dans un objet. Vous pouvez alors accéder à toutes les entrées de configuration comme si elles étaient des propriétés (ne peuvent pas obtenir beaucoup plus fortement typé que ça!)

+0

Comment cela correspond-il à mon besoin d'être fortement typé? A quel type d'objet devrais-je désérialiser? – lance

0

Une solution pourrait être,

public enum Settings 
{ 
    None, 
    DateFormatString, 
    DefeaultUserPrefix, 
    SomeOtherValue 
} 

et une classe d'aide comme,

public static class ConfigurationHelper 
{ 
    public static Get<T>(Settings setting) 
    { 
     string output = ConfigurationManager.AppSettings[setting.ToString()]; 
     if(string.isNullOrEmpty(output)) 
       throw new ConfigurationErrorsException("Setting " + setting + " is not defined in Configuration file."); 
     return (T)output; //You can probably use Convert.* functions. 
    } 
} 

Votre code d'appel ressemblera,

L'approche ci-dessus fournit un certain niveau de typage fort, mais vous devez toujours vous assurer que le nom des paramètres dans le fichier de configuration correspond au nom de l'énumération.

Le meilleur choix serait de générer automatiquement une classe en fonction du fichier de configuration.


Si vous voulez des propriétés fortement tapée, vous pouvez écrire

public static string DateFormatString 
{ 
    get { return ConfigurationHelper.Get<string>(Settings.DateFormatString); } 
} 

De plus, je vous conseille contre la lecture du fichier de configuration dans le constructeur (optimisation prématurée?). Si vous lisez le fichier de configuration dans le constructeur, cela signifie que vous ne pouvez pas modifier le fichier de configuration pendant l'exécution de l'application.

0

Je crée un emballage pour tout ce qui ne m'appartient pas directement. Cela inclut le cache, la session, la configuration, les services Web externes, etc. Cela me permet d'encapsuler les détails sales de l'utilisation de ce widget. Dans le cas de la configuration, j'ai une classe de configuration bare bones qui expose les différentes propriétés que j'ai hébergées mon app.config ou web.config.Cela peut ressembler à ceci:

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Linq; 
using System.Text; 
using RanchBuddy.Core.Services.Impl; 
using StructureMap; 

namespace RanchBuddy.Core.Services.Impl 
{ 
    [Pluggable("Default")] 
    public class ConfigurationService : IConfigurationService 
    { 
     internal static int GetDefaultCacheDuration_Days() 
     { 
      return Convert.ToInt32(ConfigurationManager.AppSettings["DefaultCacheDuration_Days"]); 
     } 

     ... 

     internal static LoggingType GetLoggingType() 
     { 
      string loggingType = ConfigurationManager.AppSettings["LoggingType"].ToString(); 
      if(loggingType.ToLower() == "verbose") 
      { 
       return LoggingType.Verbose; 
      } 
      else if (loggingType.ToLower() == "error") 
      { 
       return LoggingType.Error; 
      } 
      return LoggingType.Error; 
     } 

     ... 

     public static string GetRoot() 
     { 
      string result = ""; 
      if(ConfigurationManager.AppSettings["Root"] != null) 
      { 
       result = ConfigurationManager.AppSettings["Root"].ToString(); 
      } 
      return result; 
     } 
    } 
} 

Ici, vous pouvez faire plus que simplement obtenir des valeurs du fichier de configuration. Vous pouvez convertir une chaîne au type dont elle a besoin. Vous pouvez utiliser la chaîne pour déterminer une valeur d'énumération à renvoyer. Etc. Mais la clé est que tous les changements qui doivent être faits concernant la configuration peuvent être faits ici. A inclure si vous voulez échanger le mécanisme pour le magasin de configuration!

0

Construisez votre propre ConfigurationSection avec le Configuration Section Designer, de cette façon vous ne devez pas utiliser AppSettings du tout ... mais vous aurez votre propre collection de paramètres qui ont même IntelliSense dans le fichier web.config.

1

Il n'y a pas de duplication dans votre exemple: Une DateFormatString est un nom de propriété et l'autre est une chaîne. Vous suivez simplement une convention qui nomme la propriété de manière identique à la clé de recherche pour la valeur.

Je vois une amélioration possible. Vous devriez lire le fichier de configuration une fois dans un constructeur statique et stocker les valeurs au lieu de les lire depuis AppSettings chaque fois qu'une propriété est accédée.

+0

Bon point sur le constructeur une fois /. En ce qui concerne «pas de duplication», je ne veux pas modifier le code à deux endroits lorsque je renommer l'une des propriétés dans le fichier web.config. – lance

+0

Vous pouvez utiliser les paramètres dans un fichier de ressources au lieu de web.config. Entrez les paramètres dans l'onglet Paramètres des pages de propriétés du projet. –

Questions connexes