Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / XML
Article

Configuration By Environment

Rate me:
Please Sign up or sign in to vote.
3.42/5 (6 votes)
4 Jun 2008CPOL3 min read 30.2K   72   20   6
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
<?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
<?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
<?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)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalmachine.config vs. local web.config Pin
Joel.Wilson18710-Jun-08 4:53
Joel.Wilson18710-Jun-08 4:53 
GeneralOne solution more... Pin
Tuomas Hietanen10-Jun-08 2:34
Tuomas Hietanen10-Jun-08 2:34 
GeneralDoesn't apply to websites Pin
thany.nl4-Jun-08 21:48
thany.nl4-Jun-08 21:48 
AnswerRe: Doesn't apply to websites Pin
John Martin5-Jun-08 3:18
John Martin5-Jun-08 3:18 
GeneralAh, more reason not to use the App.Config Pin
PIEBALDconsult4-Jun-08 12:57
mvePIEBALDconsult4-Jun-08 12:57 
GeneralRe: Ah, more reason not to use the App.Config Pin
aSarafian4-Jun-08 21:15
aSarafian4-Jun-08 21:15 

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

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