Click here to Skip to main content
Click here to Skip to main content

Configuration By Environment

, 4 Jun 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
Automated method for controlling the contents of application config files based on target environment

Introduction

In all but the smallest companies, applications are frequently moved from various environments such as: Development, QA and, finally, Production. Particularly large organizations may even have User Acceptance and/or Staging environments. As applications move through these environments, elements of the application's config file such as connection strings, server names, or Web URLs must also change. This article develops a system in which data in the config file can be automatically changed to match the target environment of the application.

Background

I have seen developers use various methods to organize config files; all of which get the job done while introducing new problems at the same time. Two popular methods are given below.

Commented Sections

In this method, the application's config file contains duplicated entries for each environment and the proper sections are left uncommented while others are wrapped in comments. This method has three downsides: one is that the config file can grow quite large due to repeated text. Secondly, developers must ensure that changes are properly replicated to each duplicated section. Finally, unless an automated build tool parses the config file, developers must ensure the config file is left in a proper state for promotion to the next environment.

Multiple Config Files

In this method, a config file is created for each environment often with names like dev.config, prod.config, etc. These files are then renamed to app.config or web.config as needed. Again, unless an automated build tool renames the config file, developers must do this manually; and, because each file contains a copy of common config entries, you must ensure that changes are properly replicated to each file.

The method presented here moves configuration information common to all environments into a separate file which is then merged with environment specific information via an XSL transformation. When done as a pre-build step, this process will automatically create a config file for the proper environment.

Using the Code

The first step is to create an XML file that will contain the common configuration settings. This file will likely have an empty connectionstrings section and the appSettings that are common to all environments. An example of such a file named PreConfig.xml is shown below.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
  </configSections>
  <connectionStrings>
  </connectionStrings>
  <appSettings>
    <add key="FormatString" value="{0} {1}"/>
  </appSettings>
</configuration> 

The next step involves creating an XSLT transformation file for each environment. We will name these files matching the Configuration names we have in Visual Studio. In this example, we create a Debug and a Release file. Shown below is the transformation file Debug.xslt for the Debug environment.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="utf-8" />

  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="connectionStrings">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
      <add name="Northwind" connectionString="Data Source=localhost;
            Initial Catalog=Northwind;Integrated Security=True"
        providerName="System.Data.SqlClient" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="appSettings">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
      <add key="Salutation" value="Greetings from the DEBUG environment"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

We also create a transformation file Release.xslt for the Release environment.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="utf-8" />

  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="connectionStrings">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
      <add name="Northwind" connectionString="Data Source=ProdServer;
            Initial Catalog=Northwind;Integrated Security=True"
        providerName="System.Data.SqlClient" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="appSettings">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
      <add key="Salutation" value="Greetings from the RELEASE environment"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

And finally, you will need a Pre-Build Event command similar to the following:

cd $(ProjectDir)
msxsl Preconfig.xml $(ConfigurationName).xslt -o App.config

These commands assume that you are using Microsoft's Command Line Transformation Utility msxsl.exe. For the demonstration project, the utility was included in the project folder. If you have the tool (or a different utility) at a different location, change the pre-build event command as needed.

Points of Interest

If you leave the App.config file open in Visual Studio, you will get the "File has been modified outside the source editor" dialog with each build. This can get annoying and is easily avoided by not leaving the file open!

History

  • 4th June, 2008: Original article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

John Martin

United States United States
No Biography provided

Comments and Discussions

 
Generalmachine.config vs. local web.config Pinmemberjoelycat10-Jun-08 5:53 
GeneralOne solution more... PinmemberTuomas Hietanen10-Jun-08 3:34 
GeneralDoesn't apply to websites Pinmemberthany.org4-Jun-08 22:48 
Unfortunately, this doesn't apply to websites. At least not using our workflow. We deploy a website to a development server and see if everything works. Then we basically let a server admin do a "copy&paste" deployment to a staging server which is then test by the test team.
 
And that's where it would already fail, because the web.config is copy&pasted along with the rest of the site. We can't and won't deploy directly to a staging server, let alone a production server. There's too high a risk that something is incorrectly deployed.
 
So all in all, I'm still looking for a way to have the web.config identical throughout the local development box, the development server, the staging server and the production server...
 
--
Thany

AnswerRe: Doesn't apply to websites PinmemberJohn Martin5-Jun-08 4:18 
GeneralAh, more reason not to use the App.Config PinmemberPIEBALDconsult4-Jun-08 13:57 
GeneralRe: Ah, more reason not to use the App.Config PinmemberSarafian4-Jun-08 22:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 4 Jun 2008
Article Copyright 2008 by John Martin
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid