Introduction
This article demonstrates a simple solution to using different Property.Settings
for applications in development, acceptance, and production environments. This can be extended for using the same code base for different clients where the connection strings and other settings may be different.
Background
Visual Studio (and the .NET Framework) offers a convenient solution to adding and using application scope variables via the Settings on the Project Property pages. When different environments are configured for lifecycle stages (development, acceptance testing, and production deployment), the settings may need to be constantly changed at these stages. Connection strings and shared resource locations are the obvious settings, among others. This solution promotes the use of separate XML data files for each of the profiles (development, acceptance, and production), and the process of promoting the code base prior to deployment is as simple as changing one setting. In fact, I have found it easier to manage if the only settings in the Settings Designer are the location of the current profile file and any connection strings (as settings) used by the designers or code-behind. All of the other settings can sit in the XML data file, and be accessed via the included library API.
Using the code
The included solution has a library, a quick and dirty settings designer (I find the raw XML is just as easy), and two test harnesses. C# and VB.NET test harnesses have been supplied because the code-behind of the settings file in C# does not enumerate the built-in events.
The steps for using the test harnesses:
- From the Settings Designer (Project > Properties > Settings), assign the setting
runtimeSettingsFile
to either Profile1.xml or Profile2.xml. - Run the project.
- Note the data entries and the border color of the form.
- Close the form.
- From the Settings Designer, assign the setting
runtimeSettingsFile
to either Profile1.xml or Profile2.xml (not the last setting). - Run the project.
- Notice the data entries and border color have changed to reflect the values in the XML file. Although very simple, the two
runtimeSettings
represent different values used in development, acceptance, or production.
The steps for using the library from your project:
- Add a reference from your project to the library emx.Properties
- Create XML data files with all of the settings needed for each environment
- Set the properties of these XML files (BuildAction=Content, Copy to Output Directory=Copy, if newer)
- Add the following code to the Settings.vb or Settings.cs file (from Project > Properties > Settings > View Code)
using emx.Properties;
using System;
namespace emx.Properties.TestHarnessCS.Properties {
internal sealed partial class Settings {
public Settings() {
SettingsLoaded += SettingsLoadedHandler;
}
private void SettingsLoadedHandler(object sender,
System.Configuration.SettingsLoadedEventArgs e)
{
string s_xmlFile = System.IO.Path.Combine(_
System.Windows.Forms.Application.StartupPath, _
this["runtimeSettingsFile"].ToString());
if (!System.IO.File.Exists(s_xmlFile)){
System.Windows.Forms.MessageBox.Show(
"File does not exist:\n" + s_xmlFile);
}else{
try{
emx.Properties.Globals.currentRuntimeSettings =
new RuntimeSettings(s_xmlFile);
emx.Properties.Globals.currentRuntimeSettings.assignSettings(this);
}catch (RuntimeSettingsException ex){
System.Windows.Forms.MessageBox.Show(ex.Message +
"\nkey = " + ex.key +
"\ndataType = " + ex.dataType);
}
}
}
}
}
VB.NET:
//
Namespace My
Partial Friend NotInheritable Class MySettings
Private Sub MySettings_SettingsLoaded(ByVal sender As Object, _
ByVal e As System.Configuration.SettingsLoadedEventArgs) _
Handles Me.SettingsLoaded
Dim s_xmlFile As String = System.IO.Path.Combine(_
System.Windows.Forms.Application.StartupPath, _
Me("runtimeSettingsFile").ToString())
If Not System.IO.File.Exists(s_xmlFile) Then
System.Windows.Forms.MessageBox.Show("File does" & _
" not exist:\n" & s_xmlFile)
Else
Try
emx.Properties.Globals.currentRuntimeSettings = _
New RuntimeSettings(s_xmlFile)
emx.Properties.Globals.currentRuntimeSettings.assignSettings(Me)
Catch ex As RuntimeSettingsException
System.Windows.Forms.MessageBox.Show(ex.Message + _
"\nkey = " & ex.key & _
"\ndataType = " & ex.dataType)
End Try
End If
End Sub
End Class
End Namespace
- Add the setting
runtimeSettingsFile
with the name of the current XML file in the Settings Designer - Run your project
Points of interest
Mechanisms for updating the values of settings (connection strings included) via the Settings code-behind are discussed frequently, but I have not seen a generic component/library that manages this process. The SettingsLoaded
event is used because it is fired before any values accessed via the Settings
object are used. I am sure this process can be optimized possibly by using the SettingsBase
class instead of the strongly typed Settings
class.
The following class diagram annotates some of the features:
History
- 2009-01-08 - Minor layout edits.
- 2009-01-07 - Article submitted.