生命周期配置文件设置
一种用于划分开发、验收和生产环境设置的简单机制。
引言
本文演示了一个简单的解决方案,用于在开发、验收和生产环境中使用不同的Property.Settings
。这可以扩展为将相同的代码库用于不同的客户端,其中连接字符串和其他设置可能不同。
背景
Visual Studio(和 .NET Framework)提供了一个方便的解决方案,可以通过项目属性页面上的设置添加和使用应用程序范围的变量。当为生命周期阶段(开发、验收测试和生产部署)配置不同的环境时,可能需要在这些阶段不断更改设置。连接字符串和共享资源位置是显而易见的设置,以及其他设置。此解决方案提倡为每个配置文件(开发、验收和生产)使用单独的 XML 数据文件,并且在部署之前提升代码库的过程就像更改一个设置一样简单。事实上,我发现如果设置设计器中唯一的设置是当前配置文件的位置以及设计器或代码隐藏使用的任何连接字符串(作为设置),则更容易管理。所有其他设置都可以位于 XML 数据文件中,并通过包含的库 API 访问。
使用代码
包含的解决方案包含一个库、一个快速而粗糙的设置设计器(我发现原始 XML 同样容易),以及两个测试工具。 提供了 C# 和 VB.NET 测试工具,因为 C# 中设置文件的代码隐藏没有枚举内置事件。
使用测试工具的步骤
- 从设置设计器(项目 > 属性 > 设置),将设置
runtimeSettingsFile
分配给Profile1.xml或Profile2.xml。 - 运行项目。
- 请注意数据条目和表单的边框颜色。
- 关闭表单。
- 从设置设计器,将设置
runtimeSettingsFile
分配给Profile1.xml或Profile2.xml(不是最后一个设置)。 - 运行项目。
- 请注意数据条目和边框颜色已更改,以反映 XML 文件中的值。 虽然非常简单,但两个
runtimeSettings
代表开发、验收或生产中使用的不同值。
从您的项目中使用该库的步骤
- 从您的项目添加对库emx.Properties的引用
- 创建 XML 数据文件,其中包含每个环境所需的所有设置
- 设置这些 XML 文件的属性(BuildAction=Content,复制到输出目录=如果较新则复制)
- 将以下代码添加到Settings.vb或Settings.cs文件(从项目 > 属性 > 设置 > 查看代码)
- 在设置设计器中添加设置
runtimeSettingsFile
,其中包含当前 XML 文件的名称 - 运行你的项目
// C#
using emx.Properties;
using System;
namespace emx.Properties.TestHarnessCS.Properties {
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
internal sealed partial class Settings {
public Settings() {
SettingsLoaded += SettingsLoadedHandler;
}
private void SettingsLoadedHandler(object sender,
System.Configuration.SettingsLoadedEventArgs e)
{
// build the settings filename with the value assigned
// in Settings : System.Configuration.ApplicationSettingsBase
string s_xmlFile = System.IO.Path.Combine(_
System.Windows.Forms.Application.StartupPath, _
this["runtimeSettingsFile"].ToString());
if (!System.IO.File.Exists(s_xmlFile)){
// under normal circumstances this
// should only happen in development
System.Windows.Forms.MessageBox.Show(
"File does not exist:\n" + s_xmlFile);
}else{
try{
// set the global property
// to a new instance of the RuntimeSettings
emx.Properties.Globals.currentRuntimeSettings =
new RuntimeSettings(s_xmlFile);
// set any paired settings back
// into the Application Properties Settings
emx.Properties.Globals.currentRuntimeSettings.assignSettings(this);
}catch (RuntimeSettingsException ex){
// under normal circumstances this
// should only happen in development
System.Windows.Forms.MessageBox.Show(ex.Message +
"\nkey = " + ex.key +
"\ndataType = " + ex.dataType);
}
}
}
}
}
VB.NET
//
' VB.NET
Namespace My
'This class allows you to handle specific events on the settings class:
' The SettingChanging event is raised before a setting's value is changed.
' The PropertyChanged event is raised after a setting's value is changed.
' The SettingsLoaded event is raised after the setting values are loaded.
' The SettingsSaving event is raised before the setting values are saved.
Partial Friend NotInheritable Class MySettings
Private Sub MySettings_SettingsLoaded(ByVal sender As Object, _
ByVal e As System.Configuration.SettingsLoadedEventArgs) _
Handles Me.SettingsLoaded
' build the settings filename with the value assigned
' in Settings : System.Configuration.ApplicationSettingsBase
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
' under normal circumstances this should only happen in development
System.Windows.Forms.MessageBox.Show("File does" & _
" not exist:\n" & s_xmlFile)
Else
Try
' set the global property to a new instance of the RuntimeSettings
emx.Properties.Globals.currentRuntimeSettings = _
New RuntimeSettings(s_xmlFile)
'[ set any paired settings back
' into the Application Properties Settings
emx.Properties.Globals.currentRuntimeSettings.assignSettings(Me)
Catch ex As RuntimeSettingsException
' under normal circumstances this should only happen in development
System.Windows.Forms.MessageBox.Show(ex.Message + _
"\nkey = " & ex.key & _
"\ndataType = " & ex.dataType)
End Try
End If
End Sub
End Class
End Namespace
关注点
经常讨论通过 Settings 代码隐藏更新设置值(包括连接字符串)的机制,但我还没有看到管理此过程的通用组件/库。 使用 SettingsLoaded
事件是因为它在通过 Settings
对象访问任何值之前触发。 我相信可以通过使用 SettingsBase
类而不是强类型 Settings
类来优化此过程。
以下类图注释了一些功能
历史
- 2009-01-08 - 少量布局编辑。
- 2009-01-07 - 文章已提交。