2 votes

Des appels fortement typés dans le web.config sans dupliquer les noms de propriétés ?

J'ai cherché la réponse ici. Je suis désolé si cette question a déjà été posée (car je soupçonne que c'est le cas).

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


Détails : Dans mon code, j'essaie de minimiser l'utilisation des chaînes de caractères, et je n'aime pas définir quelque chose deux fois.

En complément de ces deux volontés, je limite l'utilisation de AppSettings (et de ses chaînes) à une seule classe, à laquelle je fais référence tout au long du projet. La classe AppSettings expose des 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 pouvez-vous recommander ?

3voto

Talljoe Points 8423

J'aime utiliser les gestionnaires de configuration personnalisés.

http://haacked.com/archive/2007/03/12/custom-configuration-sections-in-3-easy-steps.aspx

2voto

Jamie Ide Points 28680

Il n'y a pas de double emploi dans votre exemple : Un DateFormatString est un nom de propriété et l'autre est une chaîne de caractères. Vous suivez simplement une convention qui consiste à nommer la propriété de la même manière que la clé de recherche de 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.

1voto

Jason Watts Points 916

Je recommanderais probablement de désérialiser le web.config dans un objet. Vous pouvez alors accéder à toutes les entrées de configuration comme s'il s'agissait de propriétés (on ne peut pas faire plus fortement typé que ça !).

1voto

SolutionYogi Points 16697

Une solution pourrait être,

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

et ensuite avoir 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 sera le suivant,

ConfigurationHelper.Get<string>(Settings.DateFormatString);

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'enum.

Le meilleur choix serait de générer automatiquement une classe basée sur le fichier de configuration.


Si vous voulez des propriétés fortement typées, vous pouvez écrire

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

De plus, je vous déconseille de lire le 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.

1voto

Andrew Siemer Points 7226

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 de base qui expose les diverses propriétés que j'ai logées dans mon app.config ou web.config. Cela peut ressembler à quelque chose comme 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;
        }
    }
}

A l'intérieur, vous pouvez faire plus que simplement récupérer les valeurs du fichier de configuration. Vous pouvez convertir une chaîne de caractères au type qu'elle doit être. Vous pouvez utiliser la chaîne pour déterminer une valeur d'énumération à retourner. Etc. Mais l'essentiel est que toutes les modifications qui doivent être apportées à la configuration peuvent être faites ici. Y compris si vous voulez échanger le mécanisme pour le magasin de configuration !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X