Most applications I've worked on contain one or more config files. These are generally used to track web service locations, database connection strings, and logging information. Keeping these settings outside the code makes it easy to modify them without a recompile. This is especially useful when moving a deployment from dev to test, or from test to production.
On most of these projects, the preferred method used by developers is to keep multiple config files in the source repository. These are distinguished by simple renaming of the files (such as app.config, app_qa.config, app_prod.config.) In theory this should work - once you have the config files set up for each environment, deployment requires replacing the file as appropriate. And if you use a .bat file or build script, the file rename will be automatic.
The scenario usually overlooked, however, is the case where something in the config changes. Maybe a new web service is being used by the application. Or perhaps a new assembly needs to be referenced. In my experience, the developer often makes the changes to the main file (app.config), but forgets to make the same changes to the others. During development the code appears to work fine. Unfortunately, the app fails to run in the QA environment. Usually, some amount of time is spent by the developer before realizing that the problem is with the config.
To reduce this sort of issue, I recommend only keeping one config in the source repository. This config will contain the values necessary to run in the development environment. During the build process, the config is updated for the target environment. The
MSBuild Community Tasks contains a FileUpdate task that makes this easy.
Let's say you have a config file with the following:
<appSettings>
<add key="MyWebService" value="http://localhost/service/MyWebService.asmx" />
</appSettings>
The msbuild script to deploy to QA would contain:
<PropertyGroup>
<MyAppConfigFile>c:\source\MyApp\app.config</MyAppConfigFile>
<MyWebServiceRegex>http://.*/service/MyWebService.asmx</MyWebServiceRegex>
<QaWebServicePath>http://QaServer/service/MyWebService.asmx</QaWebServicePath>
</PropertyGroup>
<Target Name="ConfigureQA">
<FileUpdate
Files="$(MyAppConfigFile)"
Regex="$(MyWebServiceRegex)"
ReplacementText="$(QaWebServicePath)" />
</Target>