Configuration .NET (app.config / web.config / settings.settings)

J’ai une application .NET qui a différents fichiers de configuration pour les versions Debug et Release. Par exemple, le fichier debug app.config pointe vers un développement SQL Server sur lequel le débogage est activé et la cible de la publication pointe vers le serveur SQL en direct. Il y a aussi d’autres parameters, dont certains sont différents dans le debug / release.

J’utilise actuellement deux fichiers de configuration distincts (debug.app.config et release.app.config). J’ai un événement de construction sur le projet qui dit que s’il s’agit d’une version release, copiez release.app.config dans app.config, sinon copiez debug.app.config dans app.config.

Le problème est que l’application semble obtenir ses parameters à partir du fichier settings.settings, donc je dois ouvrir settings.settings dans Visual Studio qui m’invite ensuite à modifier les parameters pour accepter les modifications, enregistrer les parameters.settings et avoir reconstruire pour qu’il utilise les parameters corrects.

Existe-t-il une méthode meilleure / recommandée / préférée pour obtenir un effet similaire? Ou également, ai-je abordé ce problème complètement et existe-t-il une meilleure approche?

Toute configuration susceptible de différer d’un environnement à l’autre doit être stockée au niveau de la machine et non au niveau de l’ application . (Plus d’infos sur les niveaux de configuration.)

Voici les types d’éléments de configuration que je stocke généralement au niveau de la machine:

  • Paramètres de l’application
  • Chaînes de connexion
  • retail = true
  • Paramètres smtp
  • Surveillance de la santé
  • Environnement d’hébergement
  • Clé de la machine

Lorsque chaque environnement (développeur, intégration, test, étape, live) possède ses propres parameters uniques dans le répertoire c: \ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ CONFIG , vous pouvez promouvoir votre code d’application entre des environnements sans aucune modifications post-construction.

Et évidemment, le contenu du répertoire CONFIG au niveau de la machine est contrôlé par la version dans un référentiel différent ou une structure de dossier différente de votre application. Vous pouvez rendre vos fichiers .config plus conviviaux grâce à l’utilisation intelligente de configSource .

Je le fais depuis 7 ans, sur plus de 200 applications ASP.NET dans plus de 25 sociétés différentes. (Ne pas essayer de se vanter, je veux juste vous faire savoir que je n’ai jamais vu une situation où cette approche ne fonctionne pas .)

Cela pourrait aider certaines personnes travaillant avec Settings.settings et App.config: Surveillez l’atsortingbut GenerateDefaultValueInCode dans le volet Propriétés lors de la modification des valeurs de la grid Settings.settings dans Visual Studio (Visual Studio 2008 dans mon cas).

Si vous définissez GenerateDefaultValueInCode sur True (True est la valeur par défaut ici!), La valeur par défaut est compilée dans le fichier EXE (ou DLL), vous pouvez le trouver incorporé dans le fichier lorsque vous l’ouvrez dans un éditeur de texte brut.

Je travaillais sur une application console et si j’avais des valeurs par défaut dans le fichier EXE, l’application ignorait toujours la place du fichier de configuration dans le même répertoire! Un cauchemar et aucune information à ce sujet sur Internet.

Il y a une question connexe ici:

Améliorer votre processus de construction

Les fichiers de configuration permettent de remplacer les parameters:

 

Au lieu d’enregistrer deux fichiers (ou plus), vous n’inscrivez que le fichier de configuration par défaut, puis sur chaque ordinateur cible, vous placez un fichier Local.config, avec uniquement la section appSettings qui a les remplacements pour cette machine.

Si vous utilisez des sections de configuration, l’équivalent est le suivant:

 configSource="Local.config" 

Bien sûr, il est recommandé de faire des copies de sauvegarde de tous les fichiers Local.config à partir d’autres machines et de les vérifier quelque part, mais pas dans le cadre des solutions réelles. Chaque développeur place un “ignore” sur le fichier Local.config afin qu’il ne soit pas archivé, ce qui écraserait le fichier de tout le monde.

(Vous n’avez pas à l’appeler “Local.config”, c’est ce que j’utilise)

D’après ce que je lis, il semble que vous utilisiez Visual Studio pour votre processus de génération. Avez-vous pensé à utiliser MSBuild et Nant à la place?

La syntaxe XML de Nant est un peu bizarre mais une fois que vous l’aurez compris, faire ce que vous avez mentionné devient sortingvial.

             

Pour moi, il semble que vous puissiez bénéficier des projets de déploiement Web de Visual Studio 2005 .

Avec cela, vous pouvez lui demander de mettre à jour / modifier des sections de votre fichier web.config en fonction de la configuration de la construction.

Jetez un coup d’oeil à cette entrée de blog de Scott Gu pour un aperçu rapide / échantillon.

Nous utilisions des projets de déploiement Web, mais nous avons depuis migré vers NAnt. Au lieu de twigr et de copier différents fichiers de parameters, nous incorporons actuellement les valeurs de configuration directement dans le script de génération et les injectons dans nos fichiers de configuration via les tâches xmlpoke:

   

Dans les deux cas, vos fichiers de configuration peuvent avoir les valeurs de développeur souhaitées et ils fonctionneront bien dans votre environnement de développement sans casser vos systèmes de production. Nous avons constaté que les développeurs sont moins susceptibles de modifier arbitrairement les variables de script lors du test, de sorte que les erreurs de configuration accidentelles ont été plus rares qu’avec les autres techniques que nous avons essayées. la valeur de dev n’est pas poussée à produire par défaut.

Mon employeur actuel a résolu ce problème en mettant d’abord le niveau de développement (debug, stage, live, etc.) dans le fichier machine.config. Ensuite, ils ont écrit le code pour le choisir et utiliser le bon fichier de configuration. Cela a résolu le problème avec la mauvaise chaîne de connexion après le déploiement de l’application.

Ils ont récemment écrit un service Web central qui renvoie la chaîne de connexion correcte à partir de la valeur de la valeur machine.config.

Est-ce la meilleure solution? Probablement pas, mais ça marche pour eux.

L’une des solutions qui fonctionnait le mieux était l’utilisation d’un WebDeploymentProject. J’ai eu 2/3 fichiers web.config différents sur mon site, et lors de la publication, en fonction du mode de configuration sélectionné (release / staging / etc …), je copierais sur Web.Release.config et le renommerais sur le web. config dans l’événement AfterBuild, et supprimez ceux dont je n’ai pas besoin (Web.Staging.config par exemple).

          

Vous trouverez une autre solution ici: Meilleur moyen de changer de configuration entre les environnements Développement / UAT / Prod dans ASP.NET? qui utilise XSLT pour transforment le web.config.

Il y a aussi quelques bons exemples d’utilisation de NAnt.

Notre proj a le même problème où nous avons dû maintenir des configs pour dev, qa, uat et prod. Voici ce que nous avons suivi (s’applique uniquement si vous connaissez MSBuild):

Utilisez MSBuild avec l’extension des tâches de la communauté MSBuild. Il comprend la tâche «XmlMassUpdate» qui peut «mettre à jour en masse» les entrées de tout fichier XML une fois que vous lui avez donné le bon noeud pour commencer.

Implémenter:

1) Vous devez avoir un fichier de configuration qui aura vos entrées dev env; c’est le fichier de configuration de votre solution.

2) Vous devez avoir un fichier ‘Substitutions.xml’, qui contient uniquement les entrées DIFFERENT (appSettings et ConnectionSsortingngs principalement) pour chaque environnement. Les entrées qui ne changent pas d’un environnement à l’autre n’ont pas besoin d’être placées dans ce fichier. Ils peuvent vivre dans le fichier web.config de la solution et ne seront pas touchés par la tâche

3) Dans votre fichier de génération, appelez simplement la tâche de mise à jour de masse XML et fournissez l’environnement approprié en tant que paramètre.

Voir exemple ci-dessous:

                          

remplacer ‘$ Environment’ par ‘QA’ ou ‘Prod’ en fonction de ce que env. vous construisez pour. Notez que vous devez travailler sur une copie d’un fichier de configuration et non sur le fichier de configuration proprement dit pour éviter d’éventuelles erreurs non récupérables.

Il suffit de lancer le fichier de génération, puis de déplacer le fichier de configuration mis à jour dans votre environnement de déploiement et vous avez terminé!

Pour un meilleur aperçu, lisez ceci:

http://blogs.microsoft.co.il/blogs/dorony/archive/2008/01/18/easy-configuration-deployment-with-msbuild-and-the-xmlmassupdate-task.aspx

Comme vous, j’ai aussi configuré ‘multi’ app.config – par exemple app.configDEV, app.configTEST, app.config.LOCAL. Je vois certaines des excellentes alternatives suggérées, mais si vous aimez la façon dont cela fonctionne pour vous, j’appendais ce qui suit:

J’ai un

pour chaque application J’ajoute ceci à l’interface utilisateur dans la barre de titre: à partir de ConfigurationManager.AppSettings.Get (“Env”);

Je viens de renommer la config pour celle que je vise (j’ai un projet avec 8 applications avec beaucoup de firebase database / wcf config contre 4 evenioments). Pour déployer avec clickonce dans chaque je change 4 séquences dans le projet et aller. (ce que j’aimerais automatiser)

Mon seul but est de se rappeler de “tout nettoyer” après un changement, car l’ancienne configuration est “bloquée” après un renommage manuel. (Ce que je pense va réparer votre problème de réglage des parameters).

Je trouve que cela fonctionne très bien (un jour j’aurai le temps de regarder MSBuild / NAnt)

Il dit asp.net ci-dessus, alors pourquoi ne pas enregistrer vos parameters dans la firebase database et utiliser un cache personnalisé pour les récupérer?

La raison pour laquelle nous l’avons fait ici est qu’il est plus facile (pour nous) de mettre à jour la firebase database en continu que d’obtenir l’autorisation de mettre à jour en permanence les fichiers de production.

EXEMPLE d’un cache personnalisé:

 public enum ConfigurationSection { AppSettings } public static class Utility { #region "Common.Configuration.Configurations" private static Cache cache = System.Web.HttpRuntime.Cache; public static Ssortingng GetAppSetting(Ssortingng key) { return GetConfigurationValue(ConfigurationSection.AppSettings, key); } public static Ssortingng GetConfigurationValue(ConfigurationSection section, Ssortingng key) { Configurations config = null; if (!cache.TryGetItemFromCache(out config)) { config = new Configurations(); config.List(SNCLavalin.US.Common.Enumerations.ConfigurationSection.AppSettings); cache.AddToCache(config, DateTime.Now.AddMinutes(15)); } var result = (from record in config where record.Key == key select record).FirstOrDefault(); return (result == null) ? null : result.Value; } #endregion } namespace Common.Configuration { public class Configurations : List { #region CONSTRUCTORS public Configurations() : base() { initialize(); } public Configurations(int capacity) : base(capacity) { initialize(); } public Configurations(IEnumerable collection) : base(collection) { initialize(); } #endregion #region PROPERTIES & FIELDS private Crud _crud; // Db-Access layer #endregion #region EVENTS #endregion #region METHODS private void initialize() { _crud = new Crud(Utility.ConnectionName); } ///  /// Lists one-to-many records. ///  public Configurations List(ConfigurationSection section) { using (DbCommand dbCommand = _crud.Db.GetStoredProcCommand("spa_LIST_MyConfiguration")) { _crud.Db.AddInParameter(dbCommand, "@Section", DbType.Ssortingng, section.ToSsortingng()); _crud.List(dbCommand, PopulateFrom); } return this; } public void PopulateFrom(DataTable table) { this.Clear(); foreach (DataRow row in table.Rows) { Configuration instance = new Configuration(); instance.PopulateFrom(row); this.Add(instance); } } #endregion } public class Configuration { #region CONSTRUCTORS public Configuration() { initialize(); } #endregion #region PROPERTIES & FIELDS private Crud _crud; public ssortingng Section { get; set; } public ssortingng Key { get; set; } public ssortingng Value { get; set; } #endregion #region EVENTS #endregion #region METHODS private void initialize() { _crud = new Crud(Utility.ConnectionName); Clear(); } public void Clear() { this.Section = ""; this.Key = ""; this.Value = ""; } public void PopulateFrom(DataRow row) { Clear(); this.Section = row["Section"].ToSsortingng(); this.Key = row["Key"].ToSsortingng(); this.Value = row["Value"].ToSsortingng(); } #endregion } }