65.9K
CodeProject 正在变化。 阅读更多。
Home

生命周期配置文件设置

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (2投票s)

2009年1月6日

CPOL

3分钟阅读

viewsIcon

29756

downloadIcon

236

一种用于划分开发、验收和生产环境设置的简单机制。

settings_1.gif

引言

本文演示了一个简单的解决方案,用于在开发、验收和生产环境中使用不同的Property.Settings。这可以扩展为将相同的代码库用于不同的客户端,其中连接字符串和其他设置可能不同。

背景

Visual Studio(和 .NET Framework)提供了一个方便的解决方案,可以通过项目属性页面上的设置添加和使用应用程序范围的变量。当为生命周期阶段(开发、验收测试和生产部署)配置不同的环境时,可能需要在这些阶段不断更改设置。连接字符串和共享资源位置是显而易见的设置,以及其他设置。此解决方案提倡为每个配置文件(开发、验收和生产)使用单独的 XML 数据文件,并且在部署之前提升代码库的过程就像更改一个设置一样简单。事实上,我发现如果设置设计器中唯一的设置是当前配置文件的位置以及设计器或代码隐藏使用的任何连接字符串(作为设置),则更容易管理。所有其他设置都可以位于 XML 数据文件中,并通过包含的库 API 访问。

使用代码

包含的解决方案包含一个库、一个快速而粗糙的设置设计器(我发现原始 XML 同样容易),以及两个测试工具。 提供了 C# 和 VB.NET 测试工具,因为 C# 中设置文件的代码隐藏没有枚举内置事件。

使用测试工具的步骤

  1. 从设置设计器(项目 > 属性 > 设置),将设置runtimeSettingsFile分配给Profile1.xmlProfile2.xml
  2. 运行项目。
  3. 请注意数据条目和表单的边框颜色。
  4. 关闭表单。
  5. 从设置设计器,将设置runtimeSettingsFile分配给Profile1.xmlProfile2.xml(不是最后一个设置)。
  6. 运行项目。
  7. 请注意数据条目和边框颜色已更改,以反映 XML 文件中的值。 虽然非常简单,但两个 runtimeSettings 代表开发、验收或生产中使用的不同值。

从您的项目中使用该库的步骤

  1. 从您的项目添加对库emx.Properties的引用
  2. 创建 XML 数据文件,其中包含每个环境所需的所有设置
  3. 设置这些 XML 文件的属性(BuildAction=Content,复制到输出目录=如果较新则复制)
  4. xml_properties.jpg

  5. 将以下代码添加到Settings.vbSettings.cs文件(从项目 > 属性 > 设置 > 查看代码)
  6. view_code.jpg

    // 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
  7. 在设置设计器中添加设置runtimeSettingsFile,其中包含当前 XML 文件的名称
  8. 运行你的项目

关注点

经常讨论通过 Settings 代码隐藏更新设置值(包括连接字符串)的机制,但我还没有看到管理此过程的通用组件/库。 使用 SettingsLoaded 事件是因为它在通过 Settings 对象访问任何值之前触发。 我相信可以通过使用 SettingsBase 类而不是强类型 Settings 类来优化此过程。

以下类图注释了一些功能

class_diagram.jpg

历史

  • 2009-01-08 - 少量布局编辑。
  • 2009-01-07 - 文章已提交。
© . All rights reserved.