We have several .NET projects where we store certain settings in config files. Now each developer will have their own config files that differ a little (different connection strings to connect to local db, different WCF endpoints etc.)
At the moment we tend to check out app/web.config files and modify them to suit our needs. This leads to many problems since from time to time someone will check in their own settings or loose custom config when getting latest version from tfs.
My question is: how do you deal with situations like this? Or you don't have this problem at all?
We use a system that combines several of the existing answers on this page, plus draws on this suggestion by Scott Hanselman.
In short, what we did was to have a common app.config / web.config, and to have most of the specific settings in individual files, as suggested by other answers here. e.g. for our SMTP settings, the app.config contains
This file is in source control. However, the individual files, like this, are not:
That's not quite where the story ends though. What about new developers, or a fresh source installation? The bulk of the configuration is no longer in source control, and it's a pain to manually build all of the .config files they need. I prefer to have source that will at least compile right out of the box.
Therefore we do keep a version of the .config files in source control, named .config.default files. A fresh source tree therefore looks like this:
Still, not really any use to the developer, since to Visual Studio they're just meaningless text files. Hence the batch file,
copy_default_config.bat
, takes care of creating an initial set of .config files from the .config.default files:The script is safely re-runnable, in that developers who already have their .config files will not have them overwritten. Therefore, one could conceivably run this batch file as a pre-build event. The values in the .default files may not be exactly correct for a new install, but they're a reasonable starting point.
Ultimately what each developer ends up with is a folder of config files that looks something like this:
It may seem a little convoluted, but it's definitely preferable to the hassle of developers stepping on each other's toes.
In your Web.config use source from other files
Keep the web.config in version control and don't do it for ConnectionStrings.config. Now all developers have one file for the connection string.
You can do this for all the settings that are local dependant.
Here a solution for web.config files and Visual Studio 2010:
1) Edit manually your web application .csproj file to add an
AfterBuild
Target like this:This target will transform the Web.config file corresponding to the current developer logged in - hence the
$(USERNAME)
variable -, with the corresponding file created in 1). It will replace the local Web.config only if the content has changed (to avoid restart) at each build, even if the local Web.config is source controlled, that's why there is theOverwriteReadOnlyFiles
is set to True. This point in fact is arguable.2) Create a file named
Web.[developer windows login].config
for each developer in the project. (for example in the following screenshots I have two developers named smo and smo2):These files (1 per developer) can/should be source-controlled. They should not be marked as dependent on the main Web.config because we want to be able to check them out individually.
Each of this file represent a transformation to apply to the main Web.Config file. The transformation syntax is described here: Web.config Transformation Syntax for Web Application Project Deployment. We reuse this cool Xml file transformation task that comes out-of-the-box with Visual Studio. The purpose of this task is merge Xml elements and attributes instead of overwriting the whole file.
For example, here is a sample
web.[dev login].config
that changes a connection string named 'MyDB', regardless of the rest of the Web.config file:Now, this solution is not perfect because:
But at least, you only have to maintain a unique main web.config plus one transformation file per developer.
A similar approach could be taken for App.config (not web) files but I did not elaborate further.