Separating out configuration files in .NET

Occasionally we might wish to de-clutter our App.config by moving parts of the configuration into separate files. Ofcourse this process is also useful where we might wish to simply reuse existing config parts.

This capability is built into .NET, so for example we can have

<appSettings configSource="MyAppSettings.config" />

We can also use the appSettings attribute file, for example

<appSettings file="MyAppSettings.config" />

The MyAppSettings.config file might look something like

<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
  <add key="configuration" value="..\..\..\..\Samples\SpaceMonitor.xml"/>
  <add key="artifacts" value="..\..\..\..\..\Samples\artifacts"/>
</appSettings>

Note: the appSettings section starts the file (after the xml declaration), i.e. we do not have a configuration section within this file.

So this is cool, appSettings shows the configSource attribute in intellisense in Visual Studio, but we can in fact use the configSource on any section. Maybe we’ve created a section called CustomSection, then it implicitly has a configSource attribute built in.

It’s important though to note that sectionGroups do not have an implicit configSource. Say we have something like

<configSections>
  <sectionGroup name="orchestrator">
    <section name="aliases" type="Orchestrator.Configuration.AliasesSectionHandler,   
                                  Orchestrator.Configuration"/>
    <section name="plugins" type="Orchestrator.Configuration.PluginsSectionHandler, 
                                  Orchestrator.Configuration"/>
  </sectionGroup>
</configSections>

Now you might think you can write <orchestrator configSource=”Orchestrator.config”/> but I’m afraid not.

Only sections can use the configSource

Instead what we’d need to do is something like this

<orchestrator>
  <aliases configSource="Alias.config" />
  <plugins configSource="Plugins.config"/>
</orchestrator>

and the actual files would look something like

<?xml version="1.0" encoding="utf-8" ?>
<aliases>
  <alias key="cron" value="StandardTriggers.CronTrigger, StandardTriggers"/>
</aliases>

and

<?xml version="1.0" encoding="utf-8" ?>
<plugins>
  <plugin type="StandardPlugins.WCFMonitorPlugin, StandardPlugins"/>
</plugins>

So with the above information you can see that if you wanted to separate out a system.serviceModel, for example, you would only be able to separate the behaviors, services etc. as the system.serviceModel is a sectionGroup.