Est-il possible de faire quelque chose comme ce qui suit dans les fichiers app.config
ou web.config
?
<appSettings>
<add key="MyBaseDir" value="C:\MyBase" />
<add key="Dir1" value="[MyBaseDir]\Dir1"/>
<add key="Dir2" value="[MyBaseDir]\Dir2"/>
</appSettings>
Je veux ensuite accéder à Dir2 dans mon code en disant simplement:
ConfigurationManager.AppSettings["Dir2"]
Cela m'aidera lorsque j'installe mon application sur différents serveurs et emplacements où il me suffira de modifier UNE entrée dans l'ensemble de mon app.config
..__ (je sais que je peux gérer toute la concaténation en code, mais je le préfère de cette façon). .
Bonne question.
Je ne pense pas qu'il y en ait. Je pense qu'il aurait été assez bien connu s'il existait un moyen simple et je vois que Microsoft crée un mécanisme dans Visual Studio 2010 pour déployer différents fichiers de configuration à des fins de déploiement et de test.
Cela dit, cependant; J'ai constaté que, dans la section ConnectionStrings
, vous avez une sorte d'espace réservé appelé "| DataDirectory |". Peut-être pourriez-vous jeter un coup d'œil à ce qui se passe là-bas ...
Voici un morceau de machine.config
le montrant:
<connectionStrings>
<add
name="LocalSqlServer"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
Une alternative légèrement plus compliquée, mais beaucoup plus flexible, consiste à créer une classe qui représente une section de configuration. Dans votre fichier app.config
/web.config
, vous pouvez avoir ceci:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- This section must be the first section within the <configuration> node -->
<configSections>
<section name="DirectoryInfo" type="MyProjectNamespace.DirectoryInfoConfigSection, MyProjectAssemblyName" />
</configSections>
<DirectoryInfo>
<Directory MyBaseDir="C:\MyBase" Dir1="Dir1" Dir2="Dir2" />
</DirectoryInfo>
</configuration>
Ensuite, dans votre code .NET (je vais utiliser C # dans mon exemple), vous pouvez créer deux classes comme celle-ci:
using System;
using System.Configuration;
namespace MyProjectNamespace {
public class DirectoryInfoConfigSection : ConfigurationSection {
[ConfigurationProperty("Directory")]
public DirectoryConfigElement Directory {
get {
return (DirectoryConfigElement)base["Directory"];
}
}
public class DirectoryConfigElement : ConfigurationElement {
[ConfigurationProperty("MyBaseDir")]
public String BaseDirectory {
get {
return (String)base["MyBaseDir"];
}
}
[ConfigurationProperty("Dir1")]
public String Directory1 {
get {
return (String)base["Dir1"];
}
}
[ConfigurationProperty("Dir2")]
public String Directory2 {
get {
return (String)base["Dir2"];
}
}
// You can make custom properties to combine your directory names.
public String Directory1Resolved {
get {
return System.IO.Path.Combine(BaseDirectory, Directory1);
}
}
}
}
Enfin, dans votre code de programme, vous pouvez accéder à vos variables app.config
, en utilisant vos nouvelles classes, de la manière suivante:
DirectoryInfoConfigSection config =
(DirectoryInfoConfigSection)ConfigurationManager.GetSection("DirectoryInfo");
String dir1Path = config.Directory.Directory1Resolved; // This value will equal "C:\MyBase\Dir1"
Vous pouvez utiliser ma bibliothèque Expansive: http://nuget.org/List/Packages/Expansive .__ La source est disponible ici: https://github.com/anderly/Expansive
Je pensais que je venais de voir cette question.
En bref, non, il n'y a pas d'interpolation de variable dans une configuration d'application.
Vous avez deux options
Vous avez plusieurs options. Vous pouvez le faire avec une étape de construction/déploiement qui traiterait votre fichier de configuration en remplaçant vos variables par la valeur correcte.
Une autre option serait de définir votre propre section de configuration qui prend en charge cela. Par exemple, imaginez ce XML:
<variableAppSettings>
<variables>
<add key="@BaseDir" value="c:\Programs\Widget"/>
</variables>
<appSettings>
<add key="PathToDir" value="@BaseDir\Dir1"/>
</appSettings>
</variableAppSettings>
Maintenant, vous pouvez implémenter ceci en utilisant des objets de configuration personnalisés qui gèrent le remplacement des variables pour vous lors de l'exécution.
Habituellement, je finis par écrire une classe statique avec des propriétés pour accéder à chacun des paramètres de mon web.config.
public static class ConfigManager
{
public static string MyBaseDir
{
return ConfigurationManager.AppSettings["MyBaseDir"].toString();
}
public static string Dir1
{
return MyBaseDir + ConfigurationManager.AppSettings["Dir1"].toString();
}
}
Habituellement, je fais aussi des conversions de type lorsque cela est nécessaire dans cette classe. Cela permet d'avoir un accès dactylographié à votre configuration, et si les paramètres changent, vous pouvez les éditer à un seul endroit.
En règle générale, le remplacement des paramètres par cette classe est relativement facile et offre une facilité de maintenance bien supérieure.
Vous pouvez utiliser des variables d'environnement dans votre app.config
pour le scénario que vous décrivez.
<configuration>
<appSettings>
<add key="Dir1" value="%MyBaseDir%\Dir1"/>
</appSettings>
</configuration>
Ensuite, vous pouvez facilement obtenir le chemin avec:
var pathFromConfig = ConfigurationManager.AppSettings["Dir1"];
var expandedPath = Environment.ExpandEnvironmentVariables(pathFromConfig);
Dans <appSettings>
, vous pouvez créer des clés d’application,
<add key="KeyName" value="Keyvalue"/>
Plus tard, vous pourrez accéder à ces valeurs en utilisant:
ConfigurationManager.AppSettings["Keyname"]
Je vous suggérerais DslConfig . Avec DslConfig, vous pouvez utiliser les fichiers de configuration hiérarchiques de Global Config, Configuration par hôte hôte pour configurer chaque application sur chaque hôte serveur (voir AppSpike).
Si cela vous complique la tâche, vous pouvez simplement utiliser le fichier de configuration global Variables.var
Il suffit de configurer dans Varibales.var
baseDir = "C:\MyBase"
Var["MyBaseDir"] = baseDir
Var["Dir1"] = baseDir + "\Dir1"
Var["Dir2"] = baseDir + "\Dir2"
Et obtenez les valeurs de configuration avec
Configuration config = new DslConfig.BooDslConfiguration()
config.GetVariable<string>("MyBaseDir")
config.GetVariable<string>("Dir1")
config.GetVariable<string>("Dir2")
Je suis venu avec cette solution:
Je ne suis pas vraiment satisfait de cette solution car je dois modifier tous les attributs manuellement. Si j'en ajoute un nouveau, je dois le considérer dans le fichier app.xaml.cs.
Voici un extrait de code du fichier App.xaml.cs:
string configBase = Settings.Default.ConfigurationBase;
Settings.Default.CommonOutput_Directory = Settings.Default.CommonOutput_Directory.Replace("${ConfigurationBase}", configBase);
METTRE &AGRAVE; JOUR
Je viens de trouver une amélioration (à nouveau un extrait de code provenant de app.xaml.cs):
string configBase = Settings.Default.ConfigurationBase;
foreach (SettingsProperty settingsProperty in Settings.Default.Properties)
{
if (!settingsProperty.IsReadOnly && settings.Default[settingsProperty.Name] is string)
{
Settings.Default[settingsProperty.Name] = ((string)Settings.Default[settingsProperty.Name]).Replace("${ConfigurationBase}", configBase);
}
}
Maintenant, les remplacements fonctionnent pour tous les attributs de mes paramètres ayant Type = chaîne et Scope = Utilisateur. Je pense que je l'aime comme ça.
UPDATE2
Apparemment, définir Scope = Application n'est pas requis pour exécuter les propriétés.
Je recommanderais de suivre la solution de Matt Hamsmith. S'il s'agit d'un problème à implémenter, pourquoi ne pas créer une méthode d'extension qui l'implémente en arrière-plan sur la classe AppSettings?
Quelque chose comme:
public static string GetValue(this NameValueCollection settings, string key)
{
}
Dans la méthode, vous effectuez une recherche dans DictionaryInfoConfigSection à l'aide de Linq et renvoyez la valeur avec la clé correspondante. Cependant, vous aurez besoin de mettre à jour le fichier de configuration en quelque chose du genre:
<appSettings>
<DirectoryMappings>
<DirectoryMap key="MyBaseDir" value="C:\MyBase" />
<DirectoryMap key="Dir1" value="[MyBaseDir]\Dir1"/>
<DirectoryMap key="Dir2" value="[MyBaseDir]\Dir2"/>
</DirectoryMappings>
</appSettings>
Je ne pense pas que vous puissiez déclarer et utiliser des variables pour définir les clés appSettings dans un fichier de configuration. J'ai toujours géré les concaténations en code comme vous.
Je ne suis pas très à l'aise avec ce que vous voulez, mais vous pouvez ajouter un fichier de remplacement aux paramètres de l'application, puis définir ce fichier de remplacement selon l'environnement.
<appSettings file="..\OverrideSettings.config">
Pour le déploiement de produits nécessitant la configuration de nombreux éléments avec des valeurs similaires, nous utilisons de petites applications console lisant le XML et les mettant à jour en fonction des paramètres entrés. Information requise.