RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Building a Better Configuration Settings Class : Page 4

.NET provides a basic configuration management class, but it's not as flexible or easy to use as it could be. Find out how you can create a more flexible interface that provides strong typing, encryption, and write access to your application settings.

The wwAppConfiguration Class
Let's take a look under the hood and see how this class works. The wwAppConfiguration class implements two main worker methods, ReadKeysFromConfig() and WriteKeysToConfig(). Their functions aren't hard to guess. They shuttle data between the class interface and the config file.

The Read version uses Reflection to loop through all the fields and properties of the class and reads the values out of the ConfigurationSettings.AppSettings object. It performs conversions and checks to make sure that all keys exist in the configuration file. If they don't, a flag is set that causes the settings to be written out at the end. Listing 3 shows the code for the ReadPropertiesFromConfiguration.

The default constructor of the class automatically calls the ReadKeysFromConfig() method, which causes the properties of the class to be loaded with the values from the configuration file. The method then proceeds to use the MemberInfo collection and the .NET ConfigurationSettings.AppSettings class to loop through each of the fields of the object and retrieve a matching value from the AppSettings NameValueCollection. Because you need to check both properties and fields, you need to use both FieldInfo and PropertyInfo collections, making the code a little messier than it should be as there are conditional uses of either of these classes to set values.

I use the wwUtils.SetPropertyEx method to simplify the property or field setting code: this method automatically checks to see whether the item is a property or field and then uses the appropriate FieldInfo or PropertyInfo class with its appropriate Set method. This method also has logic to drill down multiple object levels using "." object syntax. You can check out this useful method and several other Reflection helpers in the supplied code in the wwUtils class.

If a value is not found in the AppSettings (null return), a flag is set notifying the code that keys are missing and need to be written out when you're finished. If a value is found, that value is read and then converted into the proper type for the field. Conversion usually involves using the Convert object except for a few types like string and Boolean, which can be converted more directly. The last type conversion is for enums. The code checks to see if the field or property is an enum and, if it is, uses the extremely handy Enum.Parse() method to turn the string value into an Enum value.

And so you loop through each field and assign its value with the matching entries from the configuration file. If there are extra keys in the configuration file, they are ignored. If there are missing keys in the configuration file, MissingFields is set and you call WriteKeysToConfig() to write the current configuration out to the configuration file.

Writing Keys to the Configuration File
The WriteKeysToConfig() method is used to write values back into the configuration file. It's used internally, but you can also call it externally to cause all of your current configuration settings to be written after you've made changes to the object.

Your Web.config changes automatically cause ASP.NET to restart the currently running application. Using this class to write keys doesn't change this behavior.
The logistics of this method are a little different from the read method, primarily because .NET doesn't provide an interface to write values back to the configuration file. ConfigurationSettings.AppSettings is a read-only interface. So in order to write out data, you'll have to do this the hard way by using XML directly. In the WriteKeysToConfig method shown in Listing 4, I use the XmlDocument class to read the entire .config file and update the AppSettings section structure.

As in the read code, the MemberInfo collection is used to loop through each of the fields in the object. But here you check against nodes that exist in the XML document using XPATH expressions. If a node is missing, it's created including (possibly) the top level AppSettings node. When the update is complete, the whole .config file is written back out to disk.

In addition to the internal requirement to write out the keys when they don't exist, it's also useful to be able to do this programmatically or interactively through the UI. Almost every application needs to be able to edit configuration settings, and editing an XML file is not my idea of a user-friendly interface. For example, Figure 1 shows a Web interface for some of the keys you were looking at earlier, and that are, in this case, databound directly against the App.Configuration object.

Figure 1. A Web Interface: Because configuration settings live in an object, it's easy to databind to the properties and in the user interface.
Any change made in the UI automatically updates the fields in the Configuration object and you can then simply write it out into the configuration. The btnSave code for this form is shown in Listing 5.

Because you have strong types and an object instance, the databinding can occur directly against the properties of your Configuration object and data can be bound directly back. (Note: This example uses databinding classes described in a previous article: "Implementing Two-Way Data Binding in ASP.NET" (CoDe Magazine, Nov/Dec 2003) but it also works with standard databinding mechanisms). All you need to do is write out the data with WriteKeysToConfig() when you're finished. It's that simple: the hardest part is creating the UI.

In Windows Forms, it's even easier if you use Properties (not fields, as I've done in the examples above) for your configuration settings. You can use the PropertyGrid to display your data simply by assigning your Config object to the SelectedObject property of the PropertyGrid; you don't even need to write any code. If you add Component attributes, you can even automatically group and attach descriptions to your settings; remember that in order for the property grid to see your properties, you need to use properties:

   [Description("The name for the Store displayed 
   in headers, confirmations etc."),
   Category("Company Information")]
   public  string StoreName 
      get { return this.cStoreName; }
      set { this.cStoreName = value; }
   string _StoreName = "West Wind Web Store";
Using a class has obvious advantages, both from a usability point of view and from a UI point of view, because you have something that you can bind to easily.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date