A common scenario is trying to maintain different values for settings when deploying for test vs the "real" release of your project. In beta1 of Visual Studio 2005, the settings designer had the concept of a "Settings profile" that was intended to at least partially solve this issue. You picked the currently active profile in the setitngs designer, and it would generate the appropriate values for the DefaultSettingValueAttribute as well as in app.config. Unfortunately, it's shortcomings were so severe that we decided to cut this functionality in the released version of VS2005 and concentrate on getting it right for the next version of Visual Studio.
So, where does this leave you? Is there any way that I can have multiple set of values for a given settings class? As it turns out, you can simulate this behavior, but it requires some manual work, and it also uses a property of the ApplicationSettingsBase class in ways that it wasn't nescessarily intended to be used in.
The ApplicationSettingsBase class has a property called SettingsKey that can be used to support having multiple instances of the same settings class, all having it's own set of values. When would you ever want to do something like that? Well, consider writing UserControl that wants to persist some of its properties. Simple, right? You create a settings class using the settings designer and simply save the settings when your user control gets Disposed. But wait a minute - what happens if the user that wants to have multiple instances of your user control on the same form? It is not very likely that they all want to share the same settings... That's where the SettingsKey property comes in. By settings the SettingsKey, you can have named instances of your settings class, and they would all get their own area of the user.config file to scribble their values in. For a settings class associated with a user control, I would probably use the control's Name as the settings key.
So, how can I (ab)use the SettingsKey property to accomplish what I want? Well, I could make sure that I use different setting key values depending on which set of values that I wanted to be used. If I wanted a specific set of values to be used in my test environment, I could make sure that I set the SettingsKey to "Test". But how would I persist the SettingsKey? Well, since we are discussing settings here, let's use a setting to store the SettingsKey that we want to use [:D]
I start by adding a new settings file and call it SettingsProfile.Settings. I add a single application scoped string value called "CurrentProfile" and set it's default value to an empty string. This is (unsurprisingly enough) where we will store the name of the current profile we want to use...
Next, I open the settings designer for the class that I want to have different values for depending on the configuration and click on the View Code button on the designer's toolbar. Unless you are using J# (which doesn't support partial classes), this will open up the part of the generated settings class where the user can freely edit stuff. We add a parameterless constructor which only needs to do one thing; assign the value SettingsKey property:
Public Class MySettings
Public Sub New()
Me.SettingsKey = SettingsProfile.Default.CurrentProfile
End Sub
End Class
Now, if we want to change the value of a setting in the "Test" profile, we can go into the app.config file, I can add a new sectionGroup declaration in my app.config file:
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ConsoleApplication116.SettingsProfile" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="ConsoleApplication116.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="ConsoleApplication116.My.MySettings.Test" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
And add the corresponding value in the the applicationSettings section of the app.config file - in the snippet below, I changed the value of the setting called "Onk", and changed the current "profile" to Test
<applicationSettings>
<ConsoleApplication116.SettingsProfile>
<setting name="Profile" serializeAs="String">
<value>Test</value>
</setting>
</ConsoleApplication116.SettingsProfile>
<ConsoleApplication116.My.MySettings>
<setting name="Onk" serializeAs="String">
<value>Release value</value>
</setting>
</ConsoleApplication116.My.MySettings>
<ConsoleApplication116.My.MySettings.Test>
<setting name="Onk" serializeAs="String">
<value>Test value</value>
</setting>
</ConsoleApplication116.My.MySettings.Test>
</applicationSettings>
So, what is the downside of doing this? Well, first of all, it assumes that you weren't already using multiple instances of the settings class with different setting keys. Second, if you have any sensitive data that you don't want to distribute once the application is ready to be released, you have to make sure that you clean up your app.config file.