1

I know that I can access application settings in .Net using Properties.Settings.Default.aSetting.

What is the best way to apply them:

  1. To directly read them in the function which relies on them. This approach eliminates some class properties or function parameters which otherwise are used to pass the settings; the function may loose its flexibility to be used with other parameters than the settings but it has this advantage that they are applied as the user change them in the settings form.
  2. Define and set corresponding member variables and parameters in classes or functions. Then how can I apply them after user changed a setting while the dependent object has been already initialized?

2 Answers 2

2

I strongly advise against using Properties.Settings.Default.aSetting all over the place.

If you do

  • You bind yourself hand and foot to whatever storage mechanism you hook up (by default the app.config and user.config files).
  • You turn every function that uses Properties.Settings.Default into something that can only be tested through slow integration tests instead of quick, fast executing and more focused unit tests.
  • You will have a hard time to arrange your tests properly as it turns out that is a lot of work, even somewhat of a hack, to get Properties.Settings.Default to work with test content instead of the actual application and user configuration files. See How do I select a .Net application configuration file from a command line parameter? and Change default app.config at runtime for more information on this.

Defining and setting member variables and parameters in classes or functions isn't very nice either as you would indeed have to come up with some sort of observer/observed (publisher/subscriber) mechanism to be able to respond to changes in settings' values.

There is a third option.

Isolate all your code from the use of Properties.Settings.Default.aSetting by wrapping it in a class you define yourself. Give that class the settings your software needs as properties. The getter and setter for each of these properties simply reads from and writes to the corresponding member in Properties.Settings.Default.aSetting.

If you ensure that the rest of your code gets a reference to an instance of your wrapper class when it needs to retrieve or store a setting, then

  • Only your wrapper class is dependent on Properties.Settings.Default.aSetting requiring integration tests.
  • All your other code can be tested with quick, fast running unit tests.

A code example using C# of this approach can be found on my blog: Property.Settings.Default makes it hard to unit test any method that uses it

1

The big value of application settings in .NET (called "Windows Forms Application Settings") is that they provide automatic persistence of settings, that can be configured per user.

Because of that, I only use them in the case of a rich client application, where I need the user to configure some settings that should persist when the user launches the application again. They are defined only by the application project, never by a library.

When the application is running, I will only use it twice:

  • At application startup, I read the Settings.Default object and put all the relevant values in my own configuration object, which is then the only one used by the application;
  • When I want to save the settings (at application exit, when the user changes settings, etc.), I write into the Settings.Default object the configuration values from my configuration object, and then call Save() on it;

As for your dilemma (between "using an object" and "passing configuration values), they can be solved by a custom, mutable, configuration object:

  • The rest of the application is passed only the configuration object (or a part of it), without knowing where it comes from (that is, no component should be coupled to the configuration by accessing it as a static property);
  • Changes made by the user while the application is running goes to my configuration object, and the rest of the application is able to read changes to the configuration object as they happen;

One thing that you might want to do is, instead of copying the data from your own model to your own object, is to define a configuration interface, that would then be implemented by the Properties.Settings class. However that can get more complex if you have nested complex objects in your settings.

And if you have many configuration settings, then you should define multiple types for it - there is no reason for the code that queries a HTTP server to have access to the user's window color.

Also, please note that using the static property Properties.Settings.Default directly falls under the case of the question:

Is a single config object a bad idea?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.