views:

801

answers:

5

I've got a relatively large .Net system that consists of a number of different applications. Rather than having lots of different app.config files, I would like to share a single configuration file between all the apps.

I would also like to have one version when developing on my machine, one version for someone else developing on their machine, one version for a test system and one version for a live system.

Is there an easy way of doing this?

+2  A: 

You could use a Post-build event (Properties -> Build Events) on your "child" projects to copy a config file from a master project to others, like this:

copy /Y c:\path\to\master\project\app.config $(TargetPath).config
exit 0

(The "exit 0" as the last line prevents a build error).

To have separate config files for different build targets ("RELEASE", "DEBUG", etc), you can edit the .csproj file (or .vbproj) in NOTEPAD.EXE to add an AppConfig tag for each of the target groups, like this:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>.\bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <AppConfig>debug.app.config</AppConfig>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>.\bin\Devel\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <AppConfig>release.app.config</AppConfig>
  </PropertyGroup>

Notice the new <AppConfig> tags present in each group.

C. Lawrence Wenham
+5  A: 

For large amounts of configuration which is needed by multiple applications, I would put this configuration into a central repository, e.g. a database, file in a common location.

To use different versions of a configuration file for different environments, create a build configuration for each of the different environments and a config file named after the environment, e.g:

production production.app.config test test.app.config

You can then use a pre build event to copy the correct config over the default app.config in your project. This will then get copied to your output directory as normal.

The pre build event would look similar to the above, just use $(Configuration) to get the appropriate file for the environment you want.

You could combine this with the above to copy the overall build specific config files into each project.

marcj
A central repository still needs some local config info (e.g. ConnectionString or whatever is required to access it). Also, some info needs to be split between local and repository (e.g. logging to be able to report "early" errors). Still doable of course, but requires some extra thoughts.
Christian.K
I suppose that the build configuration would need to be done in visual studio - I've found this to be ok, but needs quite a lot of management as it's very easy to accidentally change the build configuration. Good answer though!
Nick R
Nick R - I've only done it within Visual Studio, but don't see why MSBuild couldn't do it as well.
marcj
Christian.K - Yes indeed it does, but only a small amount and I would still recommend the ability to configure and log locally (Very useful in early failures as you say)
marcj
+2  A: 

Instead of adding <add> elements to your <appSettings> section of your config file, you can add a file= attribute to the <appSettings> element to tell it to load that data from a different file. You could then keep your common settings in that common file.

See appSettings Element (General Settings Schema) in MSDN Library.

Mike Dimmick
I do that. I'm just disappointed that the Settings.settings file (I prefer it as it strong types the settings and allow easy upgrading of configuration) doesn't offer this feature.
Julien N
A: 

You can also put the configuration settings into the machine.config to share them amongst multiple applications. This makes deployment more problematic though.

csgero
A: 

It is possible to use NTFS symbolic links to share a .NET .config file. I've seen this used successfully in a solution comprising of an ASP.NET applicaton, console applications, and more.

Alex Angas