none
Application Configuration Merge Defaults with Customisation file RRS feed

  • Question

  • I am wanting to have a configuration file which can have a default set of values in the normal app.config file.

    Then have another file which can override those default values.

    Like you can currently do for the appConfig but using the file attribute.

    The kind of settings we are doing this for is like follows

    <add name="Prod" servername="normalserver" port="60000" protocol="tcp"/>

    Then

    <add name="Prod" servername="overrideserver" port="60000" protocol="tcp"/>

     

    From reading around on the web and on the forums there doesn't seem to be any way to do this (simply).

    Does anyone have any suggestions for this?

    Monday, March 28, 2011 6:19 AM

Answers

  • Thanks for the replies but both of those methods are not what I was after.

    Since these sections are actually used in a lot of places I needed something that wasn't going to require code chagnes in so many locations.

     

    I ended up creating my own abstract ConfigurationSection i defined a property called File (I actually called it OverrideFile to make it clearer but originally it was called File)

    and i overrode the DeserializeElement( XmlReader reader, bool serializeCollectionKey ) method.

     

    I basically copied it from the AppSettingsSection from System.Configuration.

    I had to change some stuff around and copy functionallity from the internal XmlUtil, ConfigXmlReader, and ConfigXmlWriter classes.

    Once i had XmlUtil, ConfigXmlReader, and ConfigXmlWriter cut down to what i wanted it just worked without me having to get other people to change their configuration code everywhere.

     

    It seems strange that Microsoft made this stuff internal instead of just working given how often people want to do exactly what i've done there.

    Monday, April 4, 2011 7:46 AM

All replies

  • This can be done via Settings mechanism built into the VS. When you generate Settings file for your application, also object oriented properties to access them are populated inside Properties.Settings.Default class.

    The default properties are saved there as an attributes (in that accessors). That is made for such case when config file was actually deleted from the disk. The mechanism will continue work.

    So in general you can browse Properties.Settings.Default.YourItemSetting propertie for their attribute values. 

    That would look something like following: 

    // auto generated
    [global::System.Configuration.DefaultSettingValueAttribute("sasas")]
        public string Setting {
          get {
            return ((string)(this["Setting"]));
          }
          set {
            this["Setting"] = value;
          }
        }
    


    Don't forget to mark the correct answer Blog
    Monday, March 28, 2011 11:26 AM
  • Thanks for the reply but that wouldn't work for the situation I'm talking about.

    The defaults can change (thus why we want to automatically deploy the updated app.config in the first place). We don't want to deploy a new executable when the values change..

     

    I was hoping that there would be a way to do it simply.

     

    What I've had to do is i've added another section called

    <OverrideServers configSource="overrideservers.config"/>
    

    Then i manually merge the two sections.

    I needed to override IsReadOnly to return false for that collection.

    Then in the reader for it I catch and ignore ConfigurationErrorsException exceptions, that start with "Unable to open configSource file" (for when the file hasn't been created.

    I don't particularily like that solution since it doesn't seem as clean just being able to add or override items in the collection.

    Tuesday, March 29, 2011 12:20 AM
  •  

    Hi,

     

    From my understanding of your question, you need a two-layers configuration hierarchy, level 1 has the default configuration, e.g. Default.config; level 2 has the customized config, e.g. app1.config; am I right?

    if so, we can just put the Default.config to a global place which can shared by some applications, for each application, we use customized config: app.config. then, we can use ConfigurationManager.OpenExeConfiguration method to open a specified config file, in this case, we first read from app.config, if the given key does not exist, we will open the Default.config (using the OpenExeConfiguration method) to read the default value.

     

    By the way, the OpenExeConfiguration method has an overload method which accept ConfigurationUserLevel as parameter, you may have a look, hope it can helps.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, March 30, 2011 7:54 AM
  • Thanks for the replies but both of those methods are not what I was after.

    Since these sections are actually used in a lot of places I needed something that wasn't going to require code chagnes in so many locations.

     

    I ended up creating my own abstract ConfigurationSection i defined a property called File (I actually called it OverrideFile to make it clearer but originally it was called File)

    and i overrode the DeserializeElement( XmlReader reader, bool serializeCollectionKey ) method.

     

    I basically copied it from the AppSettingsSection from System.Configuration.

    I had to change some stuff around and copy functionallity from the internal XmlUtil, ConfigXmlReader, and ConfigXmlWriter classes.

    Once i had XmlUtil, ConfigXmlReader, and ConfigXmlWriter cut down to what i wanted it just worked without me having to get other people to change their configuration code everywhere.

     

    It seems strange that Microsoft made this stuff internal instead of just working given how often people want to do exactly what i've done there.

    Monday, April 4, 2011 7:46 AM