Click here to Skip to main content
15,881,172 members
Articles / Programming Languages / Visual Basic

Simplified .NET Configuration

Rate me:
Please Sign up or sign in to vote.
2.20/5 (4 votes)
18 Sep 2008CPOL6 min read 26.7K   178   20   6
A simplified wrapper to the .NET Configuration namespace.

Introduction

There's no doubt that the .NET Configuration namespace is powerful. But, that comes at a cost. The thing is enormous. And the available documentation and examples just aren't that good.

Honestly, though, the docs don't bother me that much. What bothers me is that even though the existing framework will probably do everything I'd like it to, it's just not intuitive to discover that functionality.

For instance:

  1. Why should I have to create a new ExeConfigurationFileMap object just to change the path of where the system reads its config file? Sorry, but that's about as intuitive as a car you accelerate by yodeling.
  2. Where did those ridiculous GUID/hash/hex based folder names come from? These are folders where your user level config files are stored by default. Facilitates upgrades? Yeah, maybe, but couldn't there be a better way than this?
  3. Registering ConfigurationSection handlers? Huh? Why should I have to write the full class names of classes internal to my application into my configuration file, just so that .NET can read them?

Background

What I was looking for was a simple way to create a class like:

VB
Public Sub MySettingClass
  Public Setting1 as string = ""
  Public Setting2 as Integer = 0
End Class

No need to explicitly use properties unless you need them. No need for attributes. Heck, you shouldn't even have to declare the class <Serializable>, though that's a minor point.

In lieu of coexisting within the My.Settings space, it should be able to persist itself to a config file, and then de-persist itself back when asked, like this:

VB
Settings = New MySettingsClass
Settings.Load
...
Settings.Save

Accessing your settings should be completely early bound, with all that sweet Intellisense goodness baked right in:

VB
x = Settings.Setting1
y = Setting.Setting2

Further, I should be able to easily persist sub-objects or collections made accessible off this root settings object. For example, to save a form's current position and size, and then restore it, should take code similar to:

VB
Settings.FormPositions.Save(MyForm)
Settings.FormPositions.Restore(MyForm)
Debug.print "Form position is " & Settings.FormPositions(0).Position

And a few additional requirements:

  • First, having no initial configuration file shouldn't be a problem. The entire collection of settings should easily default to some "built-in" default values when no config file exists.
  • Second, I should be able to go from 0-60 in no time. In other words, I should be able to take the .VB file for a settings base class, drop it in my application, add a settings class with the properties I need to persist, as well as a .LOAD and a .SAVE at the appropriate points in my project, and be off. No "presetting" my config file, no tweaks to anything, no registering this or that, mucking with the GAC, etc., etc.

Research

The available Microsoft documentation on the configuration system was so confusing, I believe I knew less about it after I finished reading the docs than I did when I started.

I did turn up a very good article on CodeProject by Jon Rista called Cracking the Mysteries of .NET 2.0 Configuration. Definitely worth a read if you're diving into this stuff.

While Jon gives several samples of code, nothing really illustrated exactly what I was looking for. However, there was more than enough info in the article to kick-start things for me.

Long story short, it turns out that the configuration system in .NET is, in typical MS fashion, more than capable, but overkill for many small-app type scenarios.

Using the Code

While this is definitely still a work in progress, it's proven quite useful so far, so I thought others might find it handy too.

The system consists of one file, SettingsBase.vb. It defines two classes, SettingsBase and SettingsBaseDictionary.

SettingsBaseDictionary is just a simple extension to the normal generic Dictionary class that allows it to be serialized via XML. This is something I found on the web, and is so handy with respect to settings, that I just include it directly in the file.

SettingsBase is an abstract class. To use it, you must create your own settings class (call it whatever you like) that inherits from SettingsBase:

VB
Public Class Settings
   Inherits SettingsBase
 
  Public Name As String = ""
  Public Phone As String = ""
End Class

When you want to load your settings, just instantiate your Settings object and invoke Settings.Load. To change settings, set the object's properties as you normally would.

To save your settings, invoke Settings.Save.

Finally, you'll need to add a reference to System.Configuration. Directly accessing the ConfigurationManager and EXEConfigurationFileMap objects requires it.

The sample project I've included shows several examples of this, from ridiculously simple to moderately sophisticated. I even threw in a really simple example of DataBinding to a setting property (in this case, a Dictionary of contacts).

Points of Interest

  • Your settings file will, by default, be written to the CommonApplicationData folder, and in there, in a folder named the same as the CompanyName in your assembly information screen, and in there, in a folder named the same as the Application Name on the assembly information screen.
  • Screen2.png

    Under Windows XP, that means you'll find the default settings file in c:\Documents and Settings\All Users\Application Data\{CompanyName}\{AppName}\Settings.config, and under Vista in c:\Program Data\{CompanyName}\{AppName}\Settings.config.

  • This is pretty standard practice for config files.
  • You can change the setting filename, the Company Name, and the Product Name used by simply changing the associated properties of your settings object (these properties are all inherited from the SettingsBase object).
  • Although you can use fields in your base Settings object, you won't be able to use any DataBinding support with them. This is a limitation of the .NET DataBinding support, and not with the settings class. Quite frankly, it stinks. Sometimes full blown properties make sense, but in this case, properties are just a lot more work for the same net effect.
  • If you want to use DataBinding with your settings class, you're probably best off declaring all persistent elements of your settings class as properties to begin with, and just avoid using fields at all.

  • The SettingsBase object doesn't even try to provide access to configuration "sections" or "section groups". You can easily break settings down into groups or sections by using "sub objects" off your main settings object (the one that inherits from SettingsBase). I illustrate this in the sample app.
  • As I indicated earlier, much of this could likely be accomplished by creating a custom ConfigurationSection class and registering it in your config file; but from what I can tell so far, that means you have to manually add junk to your config file. To me, that's got a code smell akin to that guy in the next cube that burns patchouli all day. It doesn't stink, per se, but it sure makes your eyes water if you're around it long enough.
  • There's not a lot of error handling here. Generally, exceptions are allowed to percolate out of this class.

What's Next

  • Really, this should be wrappable in a custom ConfigurationSection handler. My only gripes with that approach is that it doesn't resolve the folder naming problem, and it requires the goofy registration of the section handler. I'm betting there are ways around both those issues, though. I just haven't found them yet.
  • In the same vein, I'd really love to figure a way to accommodate what I'm looking for, and still use the My.Settings namespace as it's currently automatically defined by Visual Studio. I'm working on that, too, but this simple approach works for the short and sweet utility apps I've needed to turn out recently.

History

  • Sep. 2008: First version.

License

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


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalits help me Pin
Pranay Rana30-Dec-10 20:21
professionalPranay Rana30-Dec-10 20:21 
GeneralRe: its help me Pin
vbfengshui20-May-11 5:31
vbfengshui20-May-11 5:31 
GeneralFunction Pin
APTL4-Dec-08 7:56
APTL4-Dec-08 7:56 
GeneralRe: Function Pin
vbfengshui7-Dec-08 18:57
vbfengshui7-Dec-08 18:57 
GeneralRe: Function (changes for .net 2.0) Pin
dreamgarden10-Aug-10 7:51
dreamgarden10-Aug-10 7:51 
GeneralRe: Function (changes for .net 2.0) Pin
vbfengshui2-Oct-10 10:49
vbfengshui2-Oct-10 10:49 

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.