Fri
Aug 3
2007

Multi-Environment Config

The following class allows you to easily switch between DEV, TEST and PROD appConfig settings. Settings are stored in one location (your web.config or app.config file). You can define settings global to all environments and override settings for each environment as neccessary.

1. In your app, access your settings with:

MessageBox.Show("The current environment is " + Config.Name);
MessageBox.Show("The connection timeout is " + Config.ConnectionTimeout);

2. Setup your web.config or app.config as follows, with an Environment appSetting:

<?xml version="1.0"?>
<configuration>
 <appSettings>
 
   <!-- ENVIRONMENT
        Use the "Environment" key below to select the environment (DEV | TEST | PROD). 
 
        For settings common to all environments, add a normal appSetting key (e.g. "Name").
        To change a setting for a specific environment, add an appSetting key with
        the environment name (e.g. "DEV.Name"). An environment-specific setting
        will override a common setting.
 
        In the example below, the DEV environment will have a connection timeout of 
        2 minutes while the TEST and PROD environments will use 90 minutes.
   -->
 
   <add key="Environment" value="DEV"/>
 
   <add key="DEV.Name"  value="Development"/>
   <add key="TEST.Name" value="Test"/>
   <add key="PROD.Name" value="Production"/>
 
   <add key="ConnectionTimeout"     value="90"/>
   <add key="DEV.ConnectionTimeout" value="2"/>
 
 </appSettings>
</configuration>

3. Add the following Config.cs class to your project.

using System;
using System.Configuration;
using System.Collections.Generic;
using System.Text;
 
/// <summary>
/// A type-safe wapper around the project's config file. This class ensures 
/// all appSetting keys are located in one place and should provide more
/// readable code. This also allow settings to be easily moved to a database
/// or other store.
/// </summary>
public class Config
{
   /// <summary>
   /// Retrieve a value from the config file. The "environment" appsetting
   /// configures the environment (e.g. Fort Hills development, Edmonton test).
   /// Prefix appsetting with this environment value to specifiy an appsetting
   /// that is specific to the environment. 
   /// 
   /// Note: Do NOT make this method public as we want to provide a 
   /// type-safe wrapper and ensure all  constants (the appSetting keys) 
   /// are located in one place (this class).
   /// </summary>
   private static string GetValue(string key)
   {
       string env = ConfigurationManager.AppSettings["environment"];
       string fullKey = env + "." + key;
       string value = ConfigurationManager.AppSettings[fullKey];
 
       if (value == null || value == "")
           value = ConfigurationManager.AppSettings[key];
 
       if (value == null)
           value = "";
 
       return value;
   }
 
   /// <summary>
   /// Name of the environment
   /// </summary>
   public static string Name
   {
       get { return GetValue("Name").Trim(); }
   }
 
   /// <summary>
   /// Note we convert this to a TimeSpan so that users of this class
   /// don't need to know if the timeout is specified in seconds, 
   /// minutes or hours. When adding new settings convert them 
   /// to a data type that will be most useful to users of this class.
   /// </summary>
   public static TimeSpan ConnectionTimeout
   {
        get 
        { 
             return TimeSpan.FromMinutes(
                 Convert.ToDouble(GetValue("ConnectionTimeout"))); 
        }
   }
}

Leave a reply

© 2009 Brian Low. All rights reserved.