Thursday, October 02, 2014

Web.config and config file for every project in solution

Suppose a given project solution: core, data access layer and several "plugin" modules. In order to prevent changes in the core all configurations was moved to web.config. Also we would like that every module will use a dedicated config file because a "plugin" can be added and/or removed.

First solution:
In web.config file in the section "appSettings" available attribute "file" for moving segment of web config to another file. It's nice but we need more then one config file and therefore required additional configurations.Create "sectionGroup":

  1. <configuration>
  2.   <configSections>
  3.     <sectionGroup name="Plugins">
  4.         <section name="Module1" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  5.         <section name="Module2" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  6.     </sectionGroup>
  7.   </configSections>
  8. .....


Module1 and Module2 this is a names of our plugins. Create configuration section for group and define key for path of module config file in every named section:


  1.   <Plugins>
  2.     <Module1>
  3.       <add key="ConfigFile" value="App1.config"/>
  4.     </Module1>
  5.     <Module2>
  6.       <add key="ConfigFile" value="App2.config"/>
  7.     </Module2>
  8.   </Plugins>
  9.   

Create 2 new config files "App1.config" and "App2.config". In the properties of files change  "Copy to Output Directory" to "Copy always". The content of module config file look like this one:
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.   <appSettings>
  4.     <add key="AnyKey" value="Bla-Bla-Bla"/>
  5.     <add key="AnyKey2" value="Bla-Bla-Bla"/>
  6.   </appSettings>
  7. </configuration>

An using code:

  1. class Test
  2. {
  3.     private static readonly Configuration config = ConfigurationManager.OpenMappedExeConfiguration(
  4.         //Get config file
  5.         new ExeConfigurationFileMap()
  6.         {                                                                              //Web.config part   //File name                                         
  7.             ExeConfigFilename = ((NameValueCollection)ConfigurationManager.GetSection("Plugins/Module1"))["ConfigFile"]
  8.         },
  9.         ConfigurationUserLevel.None);
  10.  
  11.     private void Foo()
  12.     {
  13.         var value = config.AppSettings.Settings["AnyKey"].Value;
  14.         Console.WriteLine(value);
  15.     }
  16. }


Second solution:
Add  new section "Plugin". We are use the type DictionarySectionHandler in order to get values as Dictionary:
  1. <configuration>
  2.   <configSections>
  3.     <section name="Plugin" type="System.Configuration.DictionarySectionHandler, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  4. </configSections>

Add values:

  1. <Plugin>
  2.     <add key="ConfigFileOfModule1" value="App1.config"/>
  3.     <add key="ConfigFileOfModule2" value="App2.config"/>
  4. </Plugin>

Create 2 new config files "App1.config" and "App2.config". In the properties of files change  "Copy to Output Directory" to "Copy always". The content of module config file look like this one:
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.   <appSettings>
  4.     <add key="AnyKey" value="Bla-Bla-Bla"/>
  5.     <add key="AnyKey2" value="Bla-Bla-Bla"/>
  6.   </appSettings>
  7. </configuration>

An using code:

  1. private static readonly IDictionary section = (IDictionary)ConfigurationManager.GetSection("Plugin");
  2. private static readonly  System.Configuration.Configuration config =
  3.     ConfigurationManager.OpenMappedExeConfiguration(
  4.                         new ExeConfigurationFileMap()
  5.                         {
  6.                             ExeConfigFilename = section["ConfigFileOfModule1"].ToString()
  7.                         }, ConfigurationUserLevel.None);
  8. private void Foo()
  9. {
  10.     var value = config.AppSettings.Settings["AnyKey"].Value;
  11. }



Enjoy!