Click here to Skip to main content
13,767,957 members
Click here to Skip to main content
Add your own
alternative version

Stats

6.9K views
175 downloads
20 bookmarked
Posted 8 Apr 2018
Licenced CPOL

Making Application Settings Portable

, 10 Apr 2018
Rate this:
Please Sign up or sign in to vote.
How to create a custom settings provider for .NET applications

Introduction

This article shows how to store .NET application settings in the application's folder (or any other place) to allow them to be portable together with the app. This is achieved by creating a custom settings provider which handles loading and storing of settings.

The created class is part of a small utility library that, for example, stores your application's location and size automatically. The project can be found at https://github.com/bluegrams/MiniAppManager from where nuget packages and a demo can also be obtained.

Background

.NET provides an integrated mechanism for storing application and user settings which makes it easy for developers to create and use these settings. To give a brief overview: Settings for Windows Forms (or WPF) generally are divided into two categories: Read- and writeable user-scoped settings stored for every user account and application-scoped which are typically read-only at runtime. Both types are accessed through a settings class derived from ApplicationSettingsBase which provides the settings properties and basic methods for loading and saving.

The actual data however is provided by a class derived from SettingsProvider which handles loading and storing the data. The default settings provider stores user-scoped settings in an XML-like format in the file user.config in the AppData folder of the user. This is quite sufficient for a typical application, but in some scenarios (e.g. a portable application that should not touch the AppData folder) an alternative storage location would be preferable. As the storage location of the default settings provider can't be changed, we must implement our own settings provider. This is not quite complicated as just a few methods have to be implemented. Nevertheless, there are a few tricky points to be considered.

Using the Code

The Standard Way

Applying the portable settings provider to your application settings can simply be done within Visual Studio. To do this, go to the settings designer, select a setting and open its properties page. It contains a Provider field which is empty by default, set this to the name of the provider. Note that you must specify the full name of the class including namespaces, which is Bluegrams.Application.PortableSettingsProvider in this case.

It is also noticeable that the settings provider has to be set individually for every settings property on this way. This allows flexibility but it may not be the easiest method especially for large settings files.

The Quick Way

Therefore, this implementation of a portable settings provider provides a simpler method. To make all settings in a settings class portable, just use its ApplyProvider() method like this:

// make the default settings class portable
PortableSettingsProvider.ApplyProvider(Properties.Settings.Default);

The Config File

When applied, the portable settings provider stores the user-scoped settings in a file named portable.config in the application folder. If this file is not existent, the default values are used and a new file is created. The data is serialized in an XML-style format similar to the default settings files:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <userSettings>
    <Roaming>
      <Bluegrams.Application.WPF.Properties.Settings>
        <Culture></Culture>
      </Bluegrams.Application.WPF.Properties.Settings>
      <TestWpfApp.Properties.Settings>
        <RoamedSetting>Default text</RoamedSetting>
      </TestWpfApp.Properties.Settings>
    </Roaming>
    <PC_MachineName>
      <Bluegrams.Application.WPF.Properties.Settings>
        <Width>640</Width>
        <Height>480</Height>
        <Left>100</Left>
        <Top>100</Top>
      </Bluegrams.Application.WPF.Properties.Settings>
      <TestWpfApp.Properties.Settings>
        <LocalSetting>Default text</LocalSetting>
      </TestWpfApp.Properties.Settings>
    </PC_MachineName>
  </userSettings>
</configuration>

Several points are noticeable. First, the file is devided in a <Roaming> section and a section with the name of the current PC. Properties in the roaming section are the ones which are portable to another machine, whereas all other settings are specific to one machine (settings like window location or size should be found here). To place a setting in the roaming section, just set the Roaming property to true for that setting (see image above).

The settings properties then are further divided into the settings classes they belong to. This allows different classes from different locations to share the same settings file.

Points of Interest

A custom settings provider must only implement three methods, where GetPropertyValues() and SetPropertyValues() are the two important ones. These methods receive a collection of settings properties and perform loading or saving of the XML file. As the provider should only handle user-scoped settings and it must differentiate between roamed and non-roamed settings, the methods IsRoaming() and IsUserScoped() iterate through a property's attributes to check this. The IsRoaming() method searches for the SettingsManageabilityAttribute whereas the IsUserScoped() method indicates whether the UserScopedSettingAttribute is present.

As a third method, Initialize() must be overridden from the base class. Here, it is important to specify a value for the name argument as this argument cannot be left empty.

Next, we make sure the Reload() method works as expected. To achieve this, the settings provider does not cache any loaded XML content on its own but loads the settings from file every time the GetPropertyValues() method is called. This sounds extremely inefficient but the settings class caches the properties itself, so the settings provider only comes into action if the settings really have to be reloaded because, for example, the Reload() method is called.

As a last point of interest, have a look at the Reset() and Upgrade() methods available in every settings class. To provide support for this methods, the settings provider has to implement an interface called IApplicationSettingsProvider. In this implementation, the Reset() method simply deletes the settings file to reset all settings to their default values.

History

  • 2018-04-08: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Quanik
Germany Germany
No Biography provided

You may also be interested in...

Pro

Comments and Discussions

 
QuestionSmall Difference Pin
Ixus926-Aug-18 23:35
memberIxus926-Aug-18 23:35 
AnswerRe: Small Difference Pin
Quanik31-Aug-18 6:05
memberQuanik31-Aug-18 6:05 
GeneralRe: Small Difference Pin
Ixus96-Sep-18 20:39
memberIxus96-Sep-18 20:39 
GeneralRe: Small Difference Pin
Quanik7-Sep-18 3:31
memberQuanik7-Sep-18 3:31 
GeneralMy vote of 5 Pin
Thomas Schittli16-Apr-18 3:13
memberThomas Schittli16-Apr-18 3:13 
NewsNuget package Pin
Quanik13-Apr-18 6:54
memberQuanik13-Apr-18 6:54 
Questionnot implement inherited abstract member error Pin
Joel WZ9-Apr-18 8:51
memberJoel WZ9-Apr-18 8:51 
AnswerRe: not implement inherited abstract member error Pin
Quanik10-Apr-18 1:55
memberQuanik10-Apr-18 1:55 
GeneralRe: not implement inherited abstract member error Pin
Joel WZ10-Apr-18 5:16
memberJoel WZ10-Apr-18 5:16 
GeneralRe: not implement inherited abstract member error Pin
Quanik10-Apr-18 10:20
memberQuanik10-Apr-18 10:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05-2016 | 2.8.181116.1 | Last Updated 10 Apr 2018
Article Copyright 2018 by Quanik
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid