在我们很多程序的登陆过程中,如果对于一些复杂的内容,可能都有一些配置管理的对话框,本文介绍的混合式开发框架,是指什么呢,我下面给了一个定义。
《混合式开发框架》是指混合了传统《Winform开发框架》和《WCF开发框架》的特点,可以在两者之间自由切换,统一了系统界面层对业务服务的调用模式,所有组件模块均实现两种方式的调用,是一种弹性化非常好的框架应用,既可用于单机版软件或者基于局域网内的应用软件,也可以用于分布式技术的互联网环境应用。
对于这种混合式模式,上面说到了有两种方式,一种是常规的访问数据库方式,一种是访问WCF服务方式,而访问WCF服务,可能有基于局域网(内网)模式,也可能是基于互联网(外网)模式,那么我们就可能配置三种登陆方式,如果每次需要手工修改配置文件,可能比较麻烦,如果我们能够通过程序方式来实现参数的界面化配置,那么工作就轻松很多,也不容易出错。
关于配置的管理,我肯定是首先推荐SettingsProvider.net这个组件,大家需要了解这个组件的使用,可以参考我的随笔《Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建》,这里可以结合FireFoxDialog界面效果实现比较友好的配置管理,界面效果如下所示。
在WCF的配置文件中,我们可以看到很多对于IP地址的配置,而一般我们把WCF的配置信息放到一个独立的配置文件里面,方便管理。
对于局域网的WCF客户端的配置信息,大概效果如下所示。
而对于外网,也只是把这些IP换成公网IP即可,一般来说,这些是独立的配置文件,我们一般还有一个主配置文件**.exe.config,用来配置我们框架常用到的一些配置信息。
如下所示,在我们混合式需要访问本地数据库的时候,就可以在主配置文件里面保存主要的数据库连接信息。
前面介绍了关于参数配置和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); }
以上就是我对于混合式开发框架的登陆方式和登陆参数进行的配置信息管理的一个案例,希望对大家有帮助。