Writing a custom SettingsProvider - SqlCeSettingsProvider
18.April.08 – 9:52Visual Studio offers a nice designer for creating/editing settings for your Application. Accessing those settings via the static Settings class is a breeze and the configuration method of choice for small applications (i wouldn’t use it in larger LOB applications though).
But i was never happy how Microsoft solved the way they separated User and Application settings. It’s actually a nice idea to store the settings a user can change in a seperate (user owned) directory. But sometimes this isn’t just what you want. Why not storing the settings in a local database while still using the Visual Studio Designer for creating your settings?
I decided to write a small custom SettingsProvider that uses a Sql CE 3.5 Database to store all your settings. (that way it was nearly no work to synchronize the users settings (using the new Sync Framework) with a server. (This may look similar to Asp.Net client application services)
Let’s start. As you want to store your settings (at least some of them) strong typed, our database table contains fields for Name, Value and Type (this is actually a MyType.GetType().ToString() representation of a type).

To write your own SettingsProvider you have to inherit from System.Configuration.SettingsProvider. Therefore you have to implement the following Methods:
public SettingsPropertyValueCollection GetPropertyValues(SettingsContext context,SettingsPropertyCollection collection);
public void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection);
public string ApplicationName { get; set; }
In GetPropertyValues() we have to return a collection of SettingsPropertyValues (which we read from the local database via Linq). As we don’t save the values strong typed in the database, we have to convert them back to the corresponding type. The snippet below shows how you can read the values from database, convert them to the type you want and save them in a temporary IDictionary:
using (var db = new SqlConfigDemoDb(connStr))
{
var q2 = from c in db.Configuration select c;
foreach (Configuration conf in q2)
{
object v = Convert.ChangeType(conf.Value, Type.GetType(conf.Type));
sqldata.Add(conf.Name, v);
}
}
In SetPropertyValues() you have to write all the SettingsPropertyValue’s supplied in the collection back to the database. I.e. that you just check for a record with the corresponding name. If you find one, just change its value. If there is no record with the name, we just create a new one. (That is what is actually done when you add new Settings in the Visual Studio Designer).
When you have processed alls SettingsPropertyValues in the collection, submit your changes to the database and you are done. We are nearly finished. The last thing we have to do is adding the SettingsProviderAttribute to our Settings class. Open your Settings.settings file in Visual Studio and click the “View Code” button in the settings designer and add the following attribute:
//...
[System.Configuration.SettingsProvider(typeof(SqlConfigDemo.Config.SqlCeSettingsProvider))]
internal sealed partial class Settings {
//...
Now you can work with your Settings as usual. Access them via the static Default instance, call the Save() method to persist changes and add new Settings with the Visual Studio Settings designer. But don’t forget that you cannot change Application scope settings. At runtime you can only change User scoped settings.
The designer still edits the app.config file, but you don’t need it anymore as the settings are read from the database.
I made a small demo app showing the current Settings in a PropertyGrid. You can change the user scope settings, close the application and see the changes when you start the next time (as i call Save() when the application closes. Code is attached below.

Download SqlCeConfigDemo.zip

3 Responses to “Writing a custom SettingsProvider - SqlCeSettingsProvider”
Hey Joachim,
This is a great help! I’m still trying to figure out the .NET settings classes and how to implement my own SettingsProvider, and this is one of the clearest examples I’ve found.
One thing I’m not clear on: do you know if there is any way to change the settings provider for user settings at runtime? I’m not sure if it being an attribute would automatically prevent that or not.
Thanks again!
By Bill on Aug 21, 2008
Yes this is a great method. I have done it this way myself with one small problem. If you add a setting in the VS settings editor it removes the SettingsProvider atribute so you have to keep adding it back. Is there a way to stop this from happening?
By Alan on Apr 24, 2009
This worked great, had it working in VB.NET in no time with SQL server.
Only snag for me was that I store custom types in the configuration file so the Convert.ChangeType fails. I’m looking at replacing this with some sort of serialization method.
By Tim on Jul 9, 2009