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


How to Make Your .NET Windows Forms Configuration Files Dynamic  : Page 3

Although Windows Forms configuration files are read-only within the framework, they become dynamic XML databases when you create this AppSettingsManager class.

Building the AppSettingsManager Class
Ideally, you want full control over the section of your configuration file at runtime, including the ability to create, delete, or modify any value within that section. That means you have to compromise and accept the fact that you'll have two separate copies of the configuration file in memory—one read-only version that reflects the state of the configuration file at application startup time, and one "live" version managed by an AppSettingsManager class.

Except for the slight memory resource increase, having two versions in memory shouldn't matter, because the framework version is read-only, and after startup, it never needs to access the (possibly altered) configuration file. However you should be careful. As you've seen, the framework doesn't recognize changes to the configuration file after startup, so if you delete or change a setting via the AppSettingsManager, and then check the setting with the System.Configuration.AppSettings methods, you'll get the setting value as of application startup, not the current value. However, as long as you keep that in mind, the AppSettingsManager shouldn't interfere with any existing code that reads application settings, because it doesn't replace the System.Configuration.AppSettings functionality, it complements it.

The AppSettingsManager class fulfills the requirements. It reads the application's configuration file when you instantiate it, lets you modify the contents of the section, and saves any changes you make during class finalization.

The Singleton AppSettingsManager Class
To avoid threading problems, you only want one instance of an AppSettingsManager for any given application; otherwise, you might inadvertently create a situation where two different AppSettingsManager instances contained different data. Therefore, the AppSettingsManager constructor is private, and calling code must obtain a reference to an AppSettingsManager via the Shared GetManager method.

   Public Class AppSettingsManager
      Private Shared asm As AppSettingsManager
      Private xml As XmlDocument
      Private configFileName As String = String.Empty
      Private appSettingsElement As XmlElement
      Private dirty As Boolean = False
      Public Shared Function GetManager()
         ' Allow only one instance
         If asm Is Nothing Then
            asm = New AppSettingsManager()
            Return asm
            Return asm
         End If
      End Function
      ' more class methods here...
   End Class
Here's how the calling code looks:

      Dim settingsManager As _
         SettingsManager.AppSettingsManager = _
When the preceding statement runs, the class runs the private AppSettingsManager constructor, sets the Private Shared field asm to the resulting AppSettingsManager instance, and returns that. If the calling code executes the GetManager method again the class returns the existing asm instance. In other words, no matter how many times you call the GetManager method, all outside references to an AppSettingsManager object all point to the same instance of the class.

The AppSettingsManager Constructor
The private constructor reads the configuration file, if one exists, and readies the class to retrieve and alter the <appSettings> section data.

      Private Sub New()
         configFileName = _
         Application.ExecutablePath & ".config"
         If File.Exists(configFileName) Then
               ' Create a new XmlDocument object
               xml = New XmlDocument()
               ' load the configuration file
               ' get the <appSettings> element
               appSettingsElement = _
               xml.SelectSingleNode _
               ' if there's no <appSettings> section,
               ' create one.
               If appSettingsElement Is Nothing Then
                  appSettingsElement = _
                  xml.DocumentElement.AppendChild _
               End If
            Catch ex As Exception
               ' handle Load errors
               Throw New ApplicationException _
               ("Unable to load the configuration " & _
                "file for this application.", ex)
            End Try
            ' no configuration file exists
            ' you might want to alter this method to 
            ' create one
            Throw New ApplicationException _
            ("This application (" & _
              Application.ExecutablePath & _
              " has no configuration file.")
         End If
      End Sub
The constructor sets the String variable configFileName to the expected path of the configuration file, creates a new XmlDocument instance, and tries to load the file, trapping any errors that occur. The only error that should be able to occur is the absence of a configuration file; the framework will catch malformed configuration files during application load. The sample AppSettingsManager simply catches the error, but you may want to alter the code to create a configuration file if it doesn't already exist.

Next, the constructor obtains a reference to the <appSettings> element. If there's no <appSettings> element in the configuration file, it creates one.

After obtaining a reference to an AppSettingsManager object, you can modify the settings. Whenever you make a change to the contents, the object sets the dirty field to True, which forces the class to save the changes either when you explicitly call the Save() method, or when the overridden Finalize() method fires, whichever comes first.

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