Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Derik Whittaker

Thoughts on Software Development, .Net, OOP, Design Patterns and all things cool



How to have a Single Config File for multiple developers

In my last post I talked about how you can share a single config file among multiple project in a solution.  One of the feedback comments I got was how to have a single config file for multiple developers or even multiple environments.  So, today I thought I would chat about the different ways to handle this clumsy situation.

Scenario Overview

You have the standard app.config or web.config file and it holds values for your application.  But some of the config properties are either user specific (such as file path for local storage) or are environment specific (such as db connections, web services paths, etc).  When we deploy the application we need to ensure that the correct values are used, and we want to it with the least amount of friction.  The good news is there are many ways to skin this preverbal cat.

Option One -- Works, but is lame and painful

Probably the most common solution to this problem is also the most painful.  Simply have users 'hijack' the config file locally and modify their values.  Or when you deploy your code to another environment, you hand edit the file. 

Although this way works, it is lame and very, very error prone.  If a developer accidentally checks in his (or her) 'hijacked' copy they can then foobar others on the development team.  Or worse yet, you deploy your code and forget to change a value on in production and something really bad and painful happens.

Keep in mind one thing.  Manual processes are very error prone, avoid at all costs.

Option Two -- Getting better, but still not great

Another way that I have seen this problem solved is having multiple 'key' values in the config file.  Most of the time these values are distinguished by some sort of prefix on the key (note: there are other ways as well).   An example of this would be:
<add key="SomeQualifierHere.SomeRealKeyValue" value="SomeValue"/>

This method works, but is sloppy.  Now you have to add logic to your config file reader (please, please, please for the love of all things good, do not access your app.config file directly in your application.  Abstract that away into some class that handles this for you) to determine what 'environment' you are in and grab the right key/value pair.  The biggest issue with this method is that you add a ton of noise to the config file and you have to be very cautious when you deploy to new environments.

Option Three --  The best way

The best way that I have seen is to have a single config file, but multiple external mini-configs for each user.  This can be accomplished by using the configSource attribute items such as <connectionStrings> or <appSettings>.  This allows you to have your config file point to a single external mini-config that may be different for each user or environment.

Using the external config files you can setup either post-build events in the IDE or build actions on your build server to copy/rename/move the correct file as needed.

Because this actual topic has been talked about before in great detail, I am not going to rehash it here, instead I will point you towards 2 good resources I have used.

I hope this helps everyone,

Till next time,



Comments

Michael C. Neel said:

To build on option 3, Web Deployment Projects make it easy to change the configSource value at build time.  We have two versions of ConnectionStrings.config in source control, one for Debug builds and one for Release builds.  The Web.Config in source actually points to LocalConnectionStrings.config which isn't in source control and is specific to the developers machine.

Since running in VS or Local IIS uses the Web.Config as is, developers use their settings without need to change anything.  When they right-click the deployment project and select build, the Web.config is updated to point to the debug or release version of ConnectionStrings.config.

What I like about this setup is if a developer never installs Web Deployment Projects they can still work on the project in source control, just not build a deployment version.

# April 16, 2008 9:44 AM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# April 16, 2008 2:47 PM

Eber Irigoyen said:

"But some of the config properties are either user specific (such as file path for local storage) or are environment specific (such as db connections, web services paths, etc)."

the two links talk specifically about storing the connection strings in an external file, what about other values, like the examples you mention?

# April 17, 2008 12:43 AM

Derik Whittaker said:

@Eber,

Yes they do both talk about connection strings, but the way that it works for connection strings also works for AppSettings.

# April 17, 2008 6:18 AM

Nick Durcholz said:

Another possible solution that I have seen work very well in practice is the use of something like SED (gnuwin32.sourceforge.net/.../sed.htm).  

At a previous job, we had dozens of config files in a mixed asp classic, .net 1.1 application.  Instead of creating app.config files, we created app.config.template files and checked those into source control instead of the app.config.  The user would then run the SED utility over the source tree and it would recursively replace occurrances of defined keywords in all *.template files, and save the result without the .template.

It was a very easy and convenient way to configure the suite of applications.  As a developer, all I had to do was, get the source, create my keywords file, and run the utility.   After that there were no less than 15 global.asa's, web.config, app.config, and even .properties files that were ready to go.

# April 18, 2008 10:02 AM

Richard's Rant said:

So, how slack have I been for the last few weeks? Well, not really. I have been scrambling to finish

# April 19, 2008 5:27 PM

Greg M said:

If your SCM setup allows it, you can keep a separate config directory for each user, and another for your build system. This is pretty easy to do with (for example) clearcase views or svn externals.

# April 20, 2008 10:04 PM

fodonnel said:

The approach I am using for this problem is a simple utility I wrote: www.codeproject.com/.../configmanager_net.aspx

If run in the post build event it will execute instructions embeddded as XML comments in the app.config\web.config file.

For instance you can add an instruction to change the value of an application setting to a value from an envoirnment variable.

# June 1, 2008 9:14 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Derik Whittaker

Derik is a .Net Developer/Architect specializing in WinForms working out the northern suburbs of Chicago. He is also believer and advocate for Agile development including SCRUM, TDD, CI, etc.

When Derik is not writing code he can be found spending time with his wife and young son, climbing on his bouldering wall, watching sports (mostly baseball), and generally vegging out. Check out Devlicio.us!

Our Sponsors

Red-Gate!