Introduction
This article shows how to load application settings from a config file without recompiling the code in Visual Studio. This feature is provided by .NET automatically if your project is a single EXE. However, when I tried to do the same with DLL, this feature didn't work for me, the config file was not loading when the application started. There are many related articles, but I couldn't find a ready-for-use solution. Therefore, I've decided to take a time and contribute this article. I hope it will be useful for some folks like myself...
Background
Recently, I've been working on a plug-in (DLL) which required high level of configurability, on both user and application levels. My first choice was to utilize the app.config mechanism provided by the .NET framework. With this mechanism, application and user settings can be conveniently defined in the Visual Studio front end. And these settings are immediately available in the code through My.Settings object. Moreover, the system automatically creates a config file which is stored with the binaries. If My.Settings needs to be updated it should be possible with the Reload() method. So far, so good... Unfortunately, I've found that the config file is NOT loaded when the application starts. It means that if the user modifies the config file manually, the new values are not reflected. In order to change the config settings the user would have to use the Visual Studio and then recompile the code! . So, if we'd like to re-distribute new config file among large number of users/machines, the new settings would NOT be used. I couldn't believe that this is the right behavior for people at Microsoft, so I started looking for a solution. After spending some time on searching for a solution, I decided to write my own code to re-load setting values from the config file provided by .NET.
Using the code
To demonstrate the concept, I've created a small test application in VB.NET. The application loads settings from the config file and shows them as a property grid. As shown in bellow:
The user can open config file for editing through File->Edit, modify settings in his favorite editor and then reload these values into the application using File->Reload.
The implementation of the config file parser is provided in the SettingsHelper.vb module. One has to start from retrieving the config file handle.
Dim config = ConfigurationManager.OpenExeConfiguration(My.Application.Info.AssemblyName + ".exe")
Sections of the config file can be accessed as follows:
Dim settingsSection As ClientSettingsSection = config.GetSection(sectionName)
Then, each setting needs to be copied and converted from string to it's actual type. This type can be recovered from the My.Settings item.
For Each st As SettingElement In settingsSection.Settings
Dim name As String = st.Name
Dim value As String = st.Value.ValueXml.InnerText
Dim mySettingsItem = My.Settings.Item(name)
If mySettingsItem Is Nothing Then
Continue For
End If
Dim itemType = mySettingsItem.GetType
If itemType.Name = "StringCollection" Then
mySettingsItem.Clear()
Dim arrayOfString = st.Value.ValueXml.SelectNodes("ArrayOfString/string")
For i = 0 To arrayOfString.Count - 1
Dim newString = arrayOfString.Item(i).InnerText
mySettingsItem.Add(newString)
Next
ElseIf itemType.Name = "Color" Then
If value.Contains(",") Then
Dim rgbValues As String() = value.Split(",")
Dim r As Integer = Convert.ToInt32(rgbValues(0))
Dim g As Integer = Convert.ToInt32(rgbValues(1))
Dim b As Integer = Convert.ToInt32(rgbValues(2))
mySettingsItem = Color.FromArgb(r, g, b)
Else
mySettingsItem = Color.FromName(value)
End If
Else
Try
mySettingsItem = CTypeDynamic(value, itemType)
Catch ex As Exception
MsgBox("Cannot read " + name + " from config file!", MsgBoxStyle.Critical)
Continue For
End Try
End If
My.Settings.Item(name) = mySettingsItem
Next
Please notice, that certain types cannot be casted directly and require special treatment. In the current example, we handle StringCollection and Color, which are the most commonly used. However, you may need to extend this code in order to handle more complex types. Once the item value has been successfully retrieved it is set back into the My.Settings object.
Points of Interest
It is important to remember, that the original app.config file created by Visual Studio is copied into the Bin directory once the code is compiled. Depends on your case, you may not want to override the USER settings, but only the APPLICATION settings. User settings allow customization of the application behavior for each user, so the values for these settings are stored separately.