在我們很多程序的登陸過程中,如果對於一些復雜的內容,可能都有一些配置管理的對話框,本文介紹的混合式開發框架,是指什么呢,我下面給了一個定義。
《混合式開發框架》是指混合了傳統《Winform開發框架》和《WCF開發框架》的特點,可以在兩者之間自由切換,統一了系統界面層對業務服務的調用模式,所有組件模塊均實現兩種方式的調用,是一種彈性化非常好的框架應用,既可用於單機版軟件或者基於局域網內的應用軟件,也可以用於分布式技術的互聯網環境應用。
對於這種混合式模式,上面說到了有兩種方式,一種是常規的訪問數據庫方式,一種是訪問WCF服務方式,而訪問WCF服務,可能有基於局域網(內網)模式,也可能是基於互聯網(外網)模式,那么我們就可能配置三種登陸方式,如果每次需要手工修改配置文件,可能比較麻煩,如果我們能夠通過程序方式來實現參數的界面化配置,那么工作就輕松很多,也不容易出錯。
1、配置界面和配置內容介紹
關於配置的管理,我肯定是首先推薦SettingsProvider.net這個組件,大家需要了解這個組件的使用,可以參考我的隨筆《Winform開發框架之參數配置管理功能實現-基於SettingsProvider.net的構建》,這里可以結合FireFoxDialog界面效果實現比較友好的配置管理,界面效果如下所示。
在WCF的配置文件中,我們可以看到很多對於IP地址的配置,而一般我們把WCF的配置信息放到一個獨立的配置文件里面,方便管理。
對於局域網的WCF客戶端的配置信息,大概效果如下所示。
而對於外網,也只是把這些IP換成公網IP即可,一般來說,這些是獨立的配置文件,我們一般還有一個主配置文件**.exe.config,用來配置我們框架常用到的一些配置信息。
如下所示,在我們混合式需要訪問本地數據庫的時候,就可以在主配置文件里面保存主要的數據庫連接信息。
2、配置對話框的設計和實現
前面介紹了關於參數配置和WCF配置文件的一些相關信息,基於這些考慮,我們應該在混合式模式的登陸界面里面,設計好相關界面,讓用戶可以方便配置訪問不同的數據源,以便實現真正混合式的強大功能和便利性。
首先我們來介紹一下我的混合式框架,登陸界面的設計。
單擊參數設置按鈕,可以進入登陸訪問參數的界面對話框,在里面可以友好直觀的配置相關的WCF訪問參數,界面如下所示,這里面使用了類似FireFox的界面組件,后台的文件存儲,主要是基於本地的XML存儲,使用了SettingsProvider.net這個組件進行數據的存儲管理。
如果是選擇“單機版模式”,那么我們把對應的網絡方式設置為不可選擇,這樣的效果比較好體現本地模式的排他性。
這些界面基本上介紹了如何處理混合式開發框架的參數配置內容了,具體的實現操作是如何的呢?下面我們來一步步分析介紹下。
首先我們定義一個用來保存和加載參數的一個實體類,用來存儲對應的參數信息。
/// <summary> /// 用戶登錄的連接方式、訪問方式 /// </summary> public class LoginParameter { /// <summary> /// 系統最后登錄賬號 /// </summary> [DefaultValue("admin")] public string LoginId { get; set; } /// <summary> /// 登陸密碼 /// </summary> [ProtectedString] public string Password { get; set; } /// <summary> /// 記住密碼 /// </summary> [DefaultValue(false)] public bool RememberPassword { get; set; } /// <summary> /// 是否為本地數據庫連接方式,否則為使用WCF服務模式(內網,外網) /// </summary> [DefaultValue(false)] public bool IsLocalDatabase { get; set; } /// <summary> /// 內網WCF的主機地址 /// </summary> [DefaultValue("192.168.1.10")] public string InternalWcfHost { get; set; } /// <summary> /// 內網WCF的端口 /// </summary> [DefaultValue(8000)] public int InternalWcfPort { get; set; } /// <summary> /// 外網WCF的主機地址 /// </summary> [DefaultValue("183.6.161.193")] public string ExternalWcfHost { get; set; } /// <summary> /// 外網WCF的端口 /// </summary> [DefaultValue(8000)] public int ExternalWcfPort { get; set; } }
這樣我們就可以以實體類為載體,對數據進行獲取和保存操作了。
配置信息的加載和保存操作代碼如下所示,這些保存操作就是基於SettingsProvider.net的。
/// <summary> /// 從本地XML文件中加載參數信息 /// </summary> private void LoadParameter() { store = new PortableStorage();//保存在本地計算機 settings = new SettingsProvider(store); parameter = settings.GetSettings<LoginParameter>(); if (parameter != null) { this.cmbzhanhao.Text = parameter.LoginId; this.chkRemember.Checked = parameter.RememberPassword; if (parameter.RememberPassword) { this.tbPass.Text = parameter.Password; } else { this.tbPass.Text = ""; } this.chkLocalVersion.Checked = parameter.IsLocalDatabase; //確保為正確的訪問方式,網絡版還是單機版 SetAccessType(this.chkLocalVersion.Checked); } } /// <summary> /// 把用戶的信息保存到本地XML文件里面 /// </summary> private void SaveParameter() { store = new PortableStorage();//保存在本地計算機 settings = new SettingsProvider(store); parameter = settings.GetSettings<LoginParameter>(); if (parameter != null) { parameter.LoginId = this.cmbzhanhao.Text; if (parameter.RememberPassword) { parameter.Password = this.tbPass.Text; } else { parameter.Password = ""; } parameter.IsLocalDatabase = this.chkLocalVersion.Checked; settings.SaveSettings<LoginParameter>(parameter); } }
對於如果選擇單機版模式,那么我們需要設置相應的參數,用來告訴混合式框架采用本地數據庫模式,具體代碼如下所示。
/// <summary> /// 單機版模式的復選框事件處理 /// </summary> private void chkLocalVersion_CheckedChanged(object sender, EventArgs e) { SetAccessType(this.chkLocalVersion.Checked); } /// <summary> /// 設置為網絡方式還是單機版模式 /// </summary> /// <param name="localType">是否為單機版模式</param> private void SetAccessType(bool localType) { this.lblNetType.Enabled = !localType; this.radNetType.Enabled = !localType; AppConfig config = new AppConfig(); config.AppConfigSet("CallerType", localType ? "win" : "wcf"); ConfigurationManager.RefreshSection("appSettings"); }
如果是網絡方式,還需要區分內網模式,還是外網模式,根據參數來對相關的配置文件進行修改,具體邏輯代碼如下所示。
/// <summary> /// 網絡方式(內網、外網)切換處理事件 /// </summary> private void radNetType_SelectedIndexChanged(object sender, EventArgs e) { ChangeConfig(); } /// <summary> /// 修改配置文件 /// </summary> private void ChangeConfig() { if (parameter != null) { bool isIntranet = radNetType.EditValue.ToString() == "內網"; if (isIntranet) { UpdateConfig(parameter.InternalWcfHost, parameter.InternalWcfPort); } else { UpdateConfig(parameter.ExternalWcfHost, parameter.ExternalWcfPort); } } else { MessageDxUtil.ShowError("獲取參數信息失敗"); } } /// <summary> /// WCF模式下,修改配置文件中的主機地址信息和端口 /// </summary> /// <param name="serverIPAddress">主機地址信息</param> /// <param name="serverPort">端口</param> private void UpdateConfig(string serverIPAddress, int serverPort) { string basePath = System.Environment.CurrentDirectory; UpdateConfigFile(serverIPAddress, serverPort, Path.Combine(basePath, "BaseWcfConfig.config")); UpdateConfigFile(serverIPAddress, serverPort, Path.Combine(basePath, "WcfConfig.config")); } /// <summary> /// 通過正則標識方式替換其中的主機信息和端口參數 /// </summary> /// <param name="serverIPAddress">主機地址信息</param> /// <param name="serverPort">端口</param> /// <param name="exeFilePath">配置文件地址</param> private void UpdateConfigFile(string serverIPAddress, int serverPort, string exeFilePath) { string address = File.ReadAllText(exeFilePath, System.Text.Encoding.UTF8); string pattern = "://.*?/"; string replacement = string.Format("://{0}:{1}/", serverIPAddress, serverPort); address = Regex.Replace(address, pattern, replacement); File.WriteAllText(exeFilePath, address, System.Text.Encoding.UTF8); }
以上就是我對於混合式開發框架的登陸方式和登陸參數進行的配置信息管理的一個案例,希望對大家有幫助。