Feature Preview: Client Settings

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!