Monday, January 3, 2011

Leverage Web.config Transformation and external config files

I recently educated myself on this topic from several good online articles including MSDN and blog posts from Scott Guthrie, Scott Kirkland and Vishal Joshi.  The only major limitation I can discover in this wonderful new feature is that the web.config transformation is not invoked by debugging in Visual Studio, as explained in this asp.net forums post and elsewhere.

This limitation poses a problem for my shop and I’m sure is a frustration for any other shop with multiple developers and source code control.  In our case, we have the following requirements:

  • A set of “shared” appSettings that do not change regardless of deployment environment (debug/staging/release etc.)
  • A set of appSettings that do change for each deployment environment
  • Connection strings that change for each deployment environment

The appSettings that do change for each environment and the connection strings need careful management in source code control to avoid conflicts.  Initially I had planned to put the “shared” appSettings into the primary web.config file and then append the variable appSettings using the transformation process.  My primary web.config file and deployment environment transformation config files all would be managed using source control, and in addition each developer would have a sandbox transformation config file not under source control.  I would use a similar strategy for the connectionStrings section.  Unfortunately this strategy fails because the transformation is not invoked by debugging.

My solution is to use a combination of custom config sections, external config files, and transformation to meet all of my shop’s needs.  My solution results in more files to manage than the setup I wanted to use, but is still very manageable. 

This post provides a simplistic example with only Debug and Release configurations, but this concept can be scaled to any number of build configurations.  Here is a screen shot of a sample solution:

SolutionExplorer

Here is the Web.config file, which is used for Visual Studio debugging.  Note the custom “sharedSettings” section containing key/value pairs that do not change regardless of deployment environment and the use of external config files for the appSettings and connectionStrings sections.

<?xml version="1.0"?>
<
configuration>
  <
configSections>
    <
section name="sharedSettings" type="System.Configuration.NameValueFileSectionHandler"/>
  </
configSections>
  <
connectionStrings configSource="ConfigFiles\connectionStrings.Debug.config" />
  <
appSettings configSource="ConfigFiles\appSettings.Debug.config" />
  <
sharedSettings>
    <
add key="SharedKeyOne" value="Shared1" />
  </
sharedSettings>
  <
system.web>
    <
compilation debug="true" targetFramework="4.0" />
  </
system.web>
  <
system.webServer>
     <
modules runAllManagedModulesForAllRequests="true"/>
  </
system.webServer>
</
configuration>

Here is the Web.Release.config transformation file – transformations are used to update the connectionStrings, appSettings, and compilation debug settings.

<?xml version="1.0"?>
<
configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<
connectionStrings xdt:Transform="Replace">
<
add name="MyConnection" connectionString="my RELEASE connection string" providerName="System.Data.SqlClient"/>
</
connectionStrings>
<
appSettings xdt:Transform="Replace">
<
add key="KeyOne" value="Release1" />
<
add key="KeyTwo" value="Release2" />
</
appSettings>
<
system.web>
<
compilation xdt:Transform="RemoveAttributes(debug)" />
</
system.web>
</
configuration>

The Web.config and Web.Release.config files are managed under source code control.  The appSettings.Debug.config and connectionStrings.Debug.config files are customized locally by the developer and are not managed under source code control.

No comments:

Post a Comment