One of the new Whidbey features Joe Stegman talked about at the PDC was Client Settings. This is a feature I have spent a lot of time on in Whidbey, so I thought I would talk a little bit about it.

Very often, if you are writing a client app (also for web apps, but let me focus on client for now), you need the ability to store some settings. These settings are often user preferences, like Form size and location, look and feel of various controls, toolbar positions, last read entry etc. etc. These could also be more application specific things like connection strings and resource paths. In .NET Framework v1.0 and v1.1, there are several ways to achieve this - using dynamic properties, writing your own configuration section to store stuff into the application config file or storing the settings in a separate file, possibly in XML format, and parsing the content yourself. Ofcourse, then there is the traditional store for application settings - the Windows registry.

Each of these, however, has some limitations. Dynamic properties support a limited range of types and are read only. Writing a configuration section isn't very easy - you need to do all the parsing, merging between levels and validation yourself. Storing settings into an independent file means you need to management the deployment of that file yourself, besides, ofcourse, having to do the parsing, defining what schema to use and so on. The registry too isn't the right place to store settings in many cases.

So, if you want to store settings today, you need to put in considerable effort to do it right. The Configuration Management Application Block solves some of these problems for you today, and is pretty cool, but in Whidbey, we are taking a big step forward and are trying to design a model which makes it super easy to consume settings in your application. What's more, the core parts of this model are common to web and client apps, so there is more consistency in how you store and access settings across different kinds of applications.

At the core of the new settings infrastructure are two abstract classes - SettingsBase and SettingsProvider. SettingsBase hides the storage details way from the application developer and exposes an easy mechanism to read, write and save settings. The SettingsProvider is actually responsible for persisting these settings. How it persists them is its own choice - SettingsBase doesn't really care. It could store them in a local file, a database or retrieve them through a web service, for example. In each case, the way the application consumes the settings remains the same.

The ApplicationSettingsBase class Joe talked about adds value to SettingsBase and makes it even more easier to create your own settings. Essentially, in this model, settings are nothing but properties on classes that are decorated with a bunch of attributes that describe them.

Here is a how a simple settings class would look:

public class MySettings : ApplicationSettingsBase {
   [UserScopedSetting]  // varies by user
   [DefaultSettingValue("Blue")]  // use this if no value is stored
   public Color MyFormColor { 
       get {
             return (Color) this["MyFormColor"];
        }
        set {
              this["MyFormColor"] = value;
         }
   }

   [ApplicationScopedSetting] //shared by all users
   [SettingsProvider("MyWebServiceProvider.blahblah")]
   public Point FooLocation {
       get {
             return (Point) this["FooLocation"];
        }
        set {
              this["FooLocation"] = value;
         }
   }
}

and then consuming these settings is equally staightforward:

myForm1.BackColor = MySettings.MyFormColor;
...
MySettings.FooLocation = myControl1.Location;
...
MySettings.Save();

Its as simple as that! You can read/write settings of arbitrary types (which the provider can serialize, ofcourse) with just a few simple lines of code. By default, for client apps, we will ship a provider that can store settings into the application configuration files (we are extending the configuration system to store user specific stuff too) without any extra effort on the application developer's part!

That's not it, though. This model is also powerful for those who have more requirements. You can write your own custom provider that stores settings wherever it wants. You can exercise more control over how the default provider serializes its settings. You can define your own attributes that only your provider understands - ApplicationSettingsBase will pass the metadata over to the provider. You can group your settings into a bunch of different classes, map settings to different providers, bind the settings to properties of your UI/business objects through data binding and so on and so forth. If you wish to write your own configuration section, the ASP.NET team has made that much easier too.

That's not all we have planned - there is more, including great design time support in Visual Studio and the concept of component settings.

More on all this as we approach Whidbey Beta!