Variables within app.config/web.config
Solution 1
Good question.
I don't think there is. I believe it would have been quite well known if there was an easy way, and I see that Microsoft is creating a mechanism in Visual Studio 2010 for deploying different configuration files for deployment and test.
With that said, however; I have found that you in the ConnectionStrings
section have a kind of placeholder called "|DataDirectory|". Maybe you could have a look at what's at work there...
Here's a piece from machine.config
showing it:
<connectionStrings>
<add
name="LocalSqlServer"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
Solution 2
A slightly more complicated, but far more flexible, alternative is to create a class that represents a configuration section. In your app.config
/ web.config
file, you can have this:
<?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>
Then, in your .NET code (I'll use C# in my example), you can create two classes like this:
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);
}
}
}
}
Finally, in your program code, you can access your app.config
variables, using your new classes, in this manner:
DirectoryInfoConfigSection config =
(DirectoryInfoConfigSection)ConfigurationManager.GetSection("DirectoryInfo");
String dir1Path = config.Directory.Directory1Resolved; // This value will equal "C:\MyBase\Dir1"
Solution 3
You can accomplish using my library Expansive. Also available on nuget here.
It was designed with this as a primary use-case.
Moderate Example (using AppSettings as default source for token expansion)
In app.config:
<configuration>
<appSettings>
<add key="Domain" value="mycompany.com"/>
<add key="ServerName" value="db01.{Domain}"/>
</appSettings>
<connectionStrings>
<add name="Default" connectionString="server={ServerName};uid=uid;pwd=pwd;Initial Catalog=master;" provider="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Use the .Expand() extension method on the string to be expanded:
var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
connectionString.Expand() // returns "server=db01.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"
or
Use the Dynamic ConfigurationManager wrapper "Config" as follows (Explicit call to Expand() not necessary):
var serverName = Config.AppSettings.ServerName;
// returns "db01.mycompany.com"
var connectionString = Config.ConnectionStrings.Default;
// returns "server=db01.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"
Advanced Example 1 (using AppSettings as default source for token expansion)
In app.config:
<configuration>
<appSettings>
<add key="Environment" value="dev"/>
<add key="Domain" value="mycompany.com"/>
<add key="UserId" value="uid"/>
<add key="Password" value="pwd"/>
<add key="ServerName" value="db01-{Environment}.{Domain}"/>
<add key="ReportPath" value="\\{ServerName}\SomeFileShare"/>
</appSettings>
<connectionStrings>
<add name="Default" connectionString="server={ServerName};uid={UserId};pwd={Password};Initial Catalog=master;" provider="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Use the .Expand() extension method on the string to be expanded:
var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
connectionString.Expand() // returns "server=db01-dev.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"
Solution 4
I thought I just saw this question.
In short, no, there's no variable interpolation within an application configuration.
You have two options
- You could roll your own to substitute variables at runtime
- At build time, massage the application configuration to the particular specifics of the target deployment environment. Some details on this at dealing with the configuration-nightmare
Solution 5
Usally, I end up writing a static class with properties to access each of the settings of my 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();
}
}
Usually, I also do type conversions when required in this class. It allows to have a typed access to your config, and if settings change, you can edit them in only one place.
Usually, replacing settings with this class is relatively easy and provides a much greater maintainability.
DeeStackOverflow
Updated on September 28, 2020Comments
-
DeeStackOverflow over 3 years
Is it is possible to do something like the following in the
app.config
orweb.config
files?<appSettings> <add key="MyBaseDir" value="C:\MyBase" /> <add key="Dir1" value="[MyBaseDir]\Dir1"/> <add key="Dir2" value="[MyBaseDir]\Dir2"/> </appSettings>
I then want to access Dir2 in my code by simply saying:
ConfigurationManager.AppSettings["Dir2"]
This will help me when I install my application in different servers and locations wherein I will only have to change ONE entry in my entire
app.config
. (I know I can manage all the concatenation in code, but I prefer it this way). -
cjk about 15 yearsTo use the ConfigurationManager class you need to add a reference to System.Configuration and add a using statement for System.Configuration (imports in VB)
-
DeeStackOverflow about 15 yearsI don't see your xml in the post (indent your line 5 characters to be able to post xml tags - i had the same problem last time). Also, what are 'custom configuration objects' ? I prefer zero coding to achieve this as coding changes at this stage would set us back a lot.
-
Portman about 15 yearsCustom configuration definitely involves [simple] coding. But IMHO it is always your best option. I almost never use appSettings, preferring instead to create a custom config for every project.
-
DeeStackOverflow about 15 yearsThat is interesting information. Maybe variables are accessed using the pipe symbol ("|")? Hmm.. I wonder if this will work: <add key="Dir2" value="|MyBaseDir|\Dir2"/>
-
DeeStackOverflow about 15 yearsThis is the correct post. My previous post (same question) did not show the app.config xml entry example. I checked your link - it is too much work and prefer not to spend time there.We have separate app.configs for different boxes and i want to get away from that.
-
Michaël Carpentier about 15 yearsThe indication is correct but isn't an answer to the asked question.
-
Ahmad about 11 yearsI think this answer is very under rated!!
-
anderly about 11 yearsThanks Ahmad! Let me know how you like Expansive.
-
Ahmad about 11 yearsAlthough this is runtime 'resolution' of app settings, it solves my issues of having repetitive key value pairs. We have significantly reduce our config maintenance using this. The absolute utopia here would be to have this being a build time plugin to work in conjunction with SlowCheetah. I would +1 again if I could. Great stuff anderly.
-
TheWho over 8 yearsThere's a small error in the last line of code (not counting braces): "return System.IO.Path.Combine(MyBaseDir, Dir1);" should instead be "return System.IO.Path.Combine(BaseDirectory , Dir1);", or otherwise the method should be renamed from 'Base Directory' to 'MyBaseDir'
-
Ryan Gates almost 8 yearsCan you please provide a brief example of how your library could be used to accomplish this?
-
cowsay almost 7 yearsFor anyone else just now stumbling across this, the project has been dead for 6 years now, since 2011 :(
-
anderly almost 7 years@user1003916 The project is not dead. It just hasn't been updated since then since it's fairly stable library. Additionally, with true string interpolation now in C#, there are other options if you don't need the Expansive library features.