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 Right Environment to Support AI, Machine Learning and Deep Learning

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 Else Return asm End If End Function ' more class methods here... End Class

Here's how the calling code looks:

Dim settingsManager As _ SettingsManager.AppSettingsManager = _ AppSettingsManager.GetManager()

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 Try ' Create a new XmlDocument object xml = New XmlDocument() ' load the configuration file xml.Load(configFileName) ' get the <appSettings> element appSettingsElement = _ xml.SelectSingleNode _ ("//configuration/appSettings") ' if there's no <appSettings> section, ' create one. If appSettingsElement Is Nothing Then appSettingsElement = _ xml.CreateElement("appSettings") xml.DocumentElement.AppendChild _ (appSettingsElement) End If Catch ex As Exception ' handle Load errors Throw New ApplicationException _ ("Unable to load the configuration " & _ "file for this application.", ex) End Try Else ' 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.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



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