How to have multiple sets of application settings?

Hi,

I'm using the standard mechanism to set and retrieve application settings (using app.config, Settings.settings and Settings.Designer.cs). I can set the application settings using the Visual Studio IDE and retrieve them like this:

string title = Properties.Settings.Default.WindowTitle;

This works fine - for a single set of settings. But now I'd like to run multiple instances of my application, pass them an argument that makes them unique (1, 2, 3, or "master", "slave"), and use that argument to access a specific set of settings. Preferable something like:

string title = Properties.Settings.Master.WindowTitle;

or

string title = Properties.Settings["Master"].WindowTitle;

Is this possible The presense of the "Default" instance gives me the idea that it's possible to have other instances.

Thanks very much for any help.

Cheers from the Netherlands,

Stan



Answer this question

How to have multiple sets of application settings?

  • imdqa

    Hello All.

    Stan:

    Er, well, the settings that are available are the ones that you put in. Perhaps if you were a bit more specific about your runtime scenario.

    As to the naming, I don't see the problem, since as long as discrete versions of settings have different names, you're able to differentiate between them. But, instead of Properties.SpecialSettings, you could use Properties.MasterSettings.

    If you take the result of your runtime test for the application instance occurrence, say the third instance, then use the settings that you have defined for the third instance, like Properties.ThirdSettings.Default.SettingName.

    Forgive my presumption if I'm wrong, but it sounds like what you want is a polymorphic settings class. For that, you can derive your own base settings class from ApplicationSettingsBase, and derive subclasses from that which override the values of the properties in the base class. Then, make your instance determination, choose the correct subclass, and assign it to a base class object that represents the current chosen settings.

    HTH.



  • Michael Hansen

    Hello Mark,

    Thank you for helping me find a solution. Here's my original problem:

    I wrote an application that opens a socket for client applications to send requests to. It reads the number of the port it opens from it's configuration. If the application is very busy, I'd like to be able to start up a second instance. But that second instance cannot use the same port, so it should read another set of application settings. (I'm thinking of passing the application a command line argument it can use to look up it's settings).

    Of course, I could write my own settings reader code. But since Visual Studio offers me a solution with a simple GUI for setting the values, and generates a code module I can use to read the settings, I'm trying to "stretch" this mechanisme to handle multiple sets of configuration values.

    Back to your previous reply. The naming is not a problem. It will probably be something like Settings1 and Settings2 for the command line arguments "1" and "2". I can use a switch-statement for that, I guess (if reflection won't do the trick).

    The suggestion on deriving from a base settings class is possibly a good one. Do you think I need to "break" the code Visual Studio auto-generates for me in Settings.Designer.cs If you could point me to some example code, that would really help a lot.

    Thanks once more,

    Stan


  • CraigCody

    Hi Mark,

    Thanks for the reply. I added some more settings files to the Properties folder of my project, and I'm able to access the new settings like this:

    string windowTitle1 = Properties.Settings.Default.WindowTitle;

    string windowTitle2 = Properties.SpecialSettings.Default.WindowTitle;

    Okay, that works. But unfortunately, it's the "Settings" class name that I need to change in order to access the "new" settings, and not the "Default" property. I'd rather be able to use

    string windowTitle2 = Properties.Settings.Master.WindowTitle;

    but I guess that's not possible. Oh well.

    So, how do I figure out at runtime what sets of settings are available My first thoughts are to use System.Reflection. Is that the best way to enumerate the available sets of settings

    Thanks again for your tips.

    Stan


  • McWhirter

    Hello All.

    Stan:

    The Properties.Settings class is a class like any other, so a new instance can be created like:

    Properties.Settings newSettings = new Properties.Settings();

    The "Default" property is static on the Settings class and returns a new instance of an ApplicationSettingsBase object, cast to the type Settings.

    However, even if you had multiple instances of the Settings class, they would all still contain the same settings, as those settings are properties of the class.

    If you want different versions of settings, just add additional Settings files to your project.

    HTH.



  • Hassano21436

    Unless I missed your question, this discussion is unecessarily complicated.

    You can add additional settings files with "add new item" (or, rename the default settings.settings to any_unique_new_name.settings and use the properties design window to create a new settings.settings). Your new settings files will then be defined as Section elements in the SectionGroup of the project's app.config. Your definitions will appear in the ApplicationSettings grouped distinctly between tags that have the Section name.

    Intellisense will recognize the additional settings and, in the example (for project DemoSettings), would offer Properties.Clown1.... and Properties.Clown2.... as options. Note that Properties.Settings... will not be offered in the Intellisense list for this project because I did not retain it as one of my settings file names.

    <configuration>

    <configSections>

    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >

    <section name="DemoSettings.Properties.Clown1" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

    <section name="DemoSettings.Properties.Clown2" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

    </sectionGroup>

    </configSections>

    <applicationSettings>

    <DemoSettings.Properties.Clown1>

    <setting name="Name" serializeAs="String">

    <value>Jingles</value>

    </setting>

    <setting name="Sequence" serializeAs="String">

    <value>34</value>

    </setting>

    </DemoSettings.Properties.Clown1>

    <DemoSettings.Properties.Clown2>

    <setting name="Name" serializeAs="String">

    <value>Bozo</value>

    </setting>

    <setting name="Sequence" serializeAs="String">

    <value>62</value>

    </setting>

    </DemoSettings.Properties.Clown2>

    </applicationSettings>

    </configuration>


  • WolframW

    Hello All.

    Stan:

    Well, first off, subclassing a class derived from ApplicationSettingsBase is not as easy as I had envisioned. One has to virtually assume complete control over the settings persistence process, with a custom section handler and custom settings provider, and it takes a ton of code. Probably not the way to go in this case. Sorry for the mis-direction.

    Now, is there a reason that you can't use a single settings class for the port settings you have defined, for example:

    Properties.PortSettings.Default.FirstPort
    Properties.PortSettings.Default.SecondPort ...

    Or, going the other way, if there are multiple different settings for a given instance:

    Properties.FirstInstance.Default.PortSetting
    Properties.FirstInstance.Default.WindowTitle ...

    There probably is a way to enumerate the settings classes through Reflection (Reflection is a formidable namespace), but the code would likely be longer than a switch statement, and quite a bit more convoluted.

    If you don't want a lot of switch statements (I think switch statements have a worse reputation than they deserve, since the advent of polymorphism), then I suggest that you could make your test for the instance occurrence, use 1 switch statement to fill a "CurrentSettings" structure, and subsequently use that structure in the rest of your code.

    HTH.



  • How to have multiple sets of application settings?