Introduction
Often during the software development life-cycle, the AppSettings
values in the application's/website's configuration file must be updated. Most configuration changes occur when the project moves from Development to QA and then again to Production, since the software will need to use a different database connection string, directory paths, Web service URLs, and other settings that change during the different cycles. As is often the case, keeping configuration files in sync between Development, Test, and Production becomes a hassle, and big problems can easily occur (like if a production config file gets put back into development but is not updated with the development settings).
This article and accompanying source code demonstrates how to have a single configuration file across all cycles of development, and thereby not have to change all the AppSettings
when an application moves between the Development, Test, and Production environments. With the changing of a single AppSettings
value, the application/website can be switched over to a completely different configuration set without having to modify the rest of the configuration settings.
The AppCycleSetting Class
The class contains a static
method called GetConfigurationSetting(string sSettingName)
which is a wrapper/replacement for ConfigurationManager.AppSettings[string]
. When the GetConfigurationSetting()
method is called, the current value for the AppCycle
key is retrieved from the AppSettings
section of the configuration file. Then, the value of the AppCycle
is concatenated to the sSettingName
parameter specified. And then this new settings key is used to retrieve the specified setting from the configuration file.
Another feature is that when the AppCycle
is set to "Local
", you can also specify AppSettings
keys with your machine name to use settings that will only be used when the application runs on your machine.
An overload for the GetConfigurationSetting()
method can be used that will not apply the current AppCycle
setting to the key, so settings that do not change between life-cycles can be specified.
public static class AppCycleSetting
{
public static string GetConfigurationSetting(string sSettingName)
{
return GetConfigurationSetting(sSettingName, false);
}
public static string GetConfigurationSetting
(string sSettingName, bool bGlobalAppCycleSetting)
{
string sAppCycle = Convert.ToString
(ConfigurationManager.AppSettings["AppCycle"]);
string sAppSettingsName = string.Empty;
string sAppSettingsValue = string.Empty;
if ((bGlobalAppCycleSetting == true) ||
(sAppSettingsValue == null) || (sAppCycle.Trim() == string.Empty))
{
sAppSettingsName = string.Format("{0}", sSettingName);
}
else if (sAppCycle.ToUpper().Trim() == "LOCAL")
{
string sMachineName = System.Environment.MachineName.ToUpper().Trim();
sAppSettingsName = string.Format("{0}.{1}", sMachineName, sSettingName);
if (ConfigurationManager.AppSettings[sAppSettingsName] == null)
{
sAppSettingsName = string.Format("{0}.{1}", sAppCycle, sSettingName);
}
}
else
{
sAppSettingsName = string.Format("{0}.{1}", sAppCycle, sSettingName);
}
sAppSettingsValue = Convert.ToString
(ConfigurationManager.AppSettings[sAppSettingsName]);
if (sAppSettingsValue == null)
sAppSettingsValue = string.Empty;
return sAppSettingsValue;
}
}
Using the AppCycleSetting Class
Using the AppCycleSetting
class is very simple and easy to utilize. Typically, settings are retrieved from the configuration file by making a static
call to ConfigurationManager.AppSettings[string]
. Instead of calling that function, call the AppCycleSetting.GetConfigurationSetting()
method instead.
private void Form1_Load(object sender, EventArgs e)
{
label11.Text = AppCycleSetting.GetConfigurationSetting("AppCycle", true);
label6.Text = AppCycleSetting.GetConfigurationSetting("FileTransfer.FtpServerUrl");
label7.Text = AppCycleSetting.GetConfigurationSetting("FileTransfer.FtpUsername");
label8.Text = AppCycleSetting.GetConfigurationSetting("FileTransfer.FtpPassword");
label9.Text = AppCycleSetting.GetConfigurationSetting
("FileTransfer.FtpDestinationPath");
}
An AppCycleSetting Configuration File
<appSettings>
-->
<add key="AppCycle" value="DEV"/>
<add key="Prod.FileTransfer.FtpServerUrl" value="ftp://prod.server.com"/>
<add key="Prod.FileTransfer.FtpUsername" value="prod_user"/>
<add key="Prod.FileTransfer.FtpPassword" value="prod_pwd"/>
<add key="Prod.FileTransfer.FtpDestinationPath" value="/prod_files"/>
<add key="Test.FileTransfer.FtpServerUrl" value="ftp://test.server.com"/>
<add key="Test.FileTransfer.FtpUsername" value="test_user"/>
<add key="Test.FileTransfer.FtpPassword" value="test_pwd"/>
<add key="Test.FileTransfer.FtpDestinationPath" value="/test_files"/>
<add key="Dev.FileTransfer.FtpServerUrl" value="ftp://dev.server.com"/>
<add key="Dev.FileTransfer.FtpUsername" value="dev_user"/>
<add key="Dev.FileTransfer.FtpPassword" value="dev_pwd"/>
<add key="Dev.FileTransfer.FtpDestinationPath" value="/dev_files"/>
<add key="Local.FileTransfer.FtpServerUrl" value="ftp://local.server.com"/>
<add key="Local.FileTransfer.FtpUsername" value="local_user"/>
<add key="Local.FileTransfer.FtpPassword" value="local_pwd"/>
<add key="Local.FileTransfer.FtpDestinationPath" value="/local_files"/>
<add key="MYMACHINENAME.FileTransfer.FtpDestinationPath" value="/my_files"/>
</appSettings>
Conclusion
I hope you find this article useful - I've found that it has greatly reduced deployment issues as they pertain to the configuration settings.
History
- 22nd November, 2006: Initial post