Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Helper Class for Development/Test/Release Configuration Files

0.00/5 (No votes)
22 Nov 2006 1  
An article on how to make a single configuration file for the entire development life-cycle
Sample Image - main.jpg

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
{
    /// <SUMMARY>
    /// Returns the config value for the specified settings key 
    /// with the active AppCycle setting applied
    /// </SUMMARY>
    /// <param name="sSettingName"></param>
    /// <RETURNS></RETURNS>
    public static string GetConfigurationSetting(string sSettingName)
    {
        return GetConfigurationSetting(sSettingName, false);
    }

    /// <SUMMARY>
    /// Returns the config value for the specified settings key 
    /// with the active AppCycle setting applied
    /// NOTES:  the AppCycle setting can be overridden by specifying: 
    /// bGlobalAppCycleSetting=True
    ///         if LOCAL cycle, it checks for settings specific to your machine name; 
    ///         if not found, uses "LOCAL" settings
    /// </SUMMARY>
    /// <param name="sSettingName"></param>
    /// <param name="bGlobalAppCycleSetting"></param>
    /// <RETURNS></RETURNS>
    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))
        {
            // if cycle setting is empty or disabled for this item, 
            // just use the setting key
            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 machine name is not found in the settings, 
            // then default to the appcycle setting (LOCAL)
            if (ConfigurationManager.AppSettings[sAppSettingsName] == null)
            {
                // concatenate the cycle setting to the setting key 
                sAppSettingsName = string.Format("{0}.{1}", sAppCycle, sSettingName);
            }
        }
        else
        {
            // concatenate the cycle setting to the setting key 
            sAppSettingsName = string.Format("{0}.{1}", sAppCycle, sSettingName);
        }

        // get the setting from the config file
        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)
{   
    // read the settings from the AppSettings section of the configuration file
    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>
    <!-- Use AppCycle value to determine what state the application is in.
         Use for what database to point to as well as other functions.
         Settings:  "Prod", "Test", "Dev", "Local"     -->

    <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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here