In my opinion, there are a couple of things that combine in the current .NET Framework to form a void (wait, can two things combine to form a void)?
Those two things are the strong preference for .config files over
registry storage (a preference I agree with), and the lack of API
support for writing config files.
The ConfigurationSettings class is great for reading your app.config or web.config file... but that file is specific to an application
and not to a user. So while it's useful for storing things that are
typically app-wide (database connection details, logging levels, etc),
it's pretty much useless for storing user preferences. These usually
include things like remembering a user's window size/positions,
preferred file locations, or other user-specific settings.
There are lots
of articles and samples online that suggest options for getting around
these limitations. My opinion is that most of them fall just short of
being complete solutions, though, and the reasons tend to be along
these lines:
They don't allow for strongly-typed access to the preferences.
To be really useful, reading and writing preferences should be
idiot-level simple for the developer. If the dev has to write several
lines of code to cast preference values to/from a string for storage,
they're gonna skip it. The result is an app that's less flexible for
the user than it could be. Another benefit of strongly typing the
preferences API is that Intellisense helps the dev access the settings
without having to remember key names.
They use INI files or the registry.
Since the release of .NET 1.0, MS has steered developers away from
using the registry. The registry is generally recognized to be a system
that's prone to corruption and using this approach makes XCopy
deployment a real pain. INI files are a fairly simple way to go, but
they don't allow for a nested hierarchy and you end up dealing with a
lot of parsing code. You also can't easily define metadata
about each setting. .NET gives us a fairly rich set of APIs
for XML, so why not use them?
They provide write-access to app.config. There are some articles that provide a wrapper for the app.config so that the developer can read and write
to the file. There are a couple of problems with this -- first is that
it's an app-wide file so all the user profiles on a shared machine will
have the same settings. Second, app.config is in the application's
startup directory, which is usually under \Program Files\.
Standard user accounts under Windows don't have the ability to modify
program files, so this option only works for Admin or Power User
accounts. A better solution is to store preference files under a user's
profile (\Document and Settings\[user]\Application Data\) -- even better is IsolatedStorage.
They use lots of files.
Many articles and samples use XML serialization as a way to read/write
preferences. It works well, but the suggestion is often to have a base Settings
class and then many component-specific subclasses. Each component
manages its own settings class, reading and
writing as needed and then calling inherited members to serialize
and deserialize the object. Maybe this isn't much of a problem,
but for some reason it seems less elegant to me. The apps I work on
tend to be large, modular Winforms apps -- lots of individual
components, in which case I'd end up with a lots of files on the user's
machine. Also in this scenario, components actually have to be aware of
two types of settings -- their own settings and the app-wide settings
that the user specifies. It gets worse if you have components that want
to share some types of settings.
So do I have a solution for all
this? Not yet. But I am reading as many articles and samples as I can
find, making lots of notes, and trying to form a clear picture of what
I think would be the "mother of all settings APIs".
Admittedly, this would be with a bias toward Winforms
apps. So far, there are two recent articles that are along the
lines of what I'm thinking. These are Building a Better Configuration Settings Class (by Rick Strahl) and Manage Users Settings in Your .NET App with Custom Preferences API (Ray Djajadinata in July's MSDN Mag). Both of them offer good, complete coverage of the issues associated with a settings API.
At
work last year, I built a fairly basic XML-based API that stores user
preferences but it does suffer from a couple of the problems above --
most notable is that it's not strongly-typed. So... my current plan is
to spend some off-hours going through the two articles above, continue
to make note of the various ideas that are brewing, and then
coming up with a new design that incorporates the pieces and parts that
I think are important.
So with all that... am I missing any other key needs from a preferences API?
