在C#应用中,设计自己的配置文件

  在系统开发的过程中,我们总是需要使用配置文件来保存一些我们需要保存的系统参数,毕竟这是.Net时代,如果再使用注册表那就显得复杂了,毕竟操作注册表的API并不是哪么容易理解的。

所以在.net应用程序中,都默认出现一个App.Config(对于 Web应用程序是Web.Config)我们可以将系统运行所需要的参数采用加密或者明文的方式保存在这个文件中。但是当我们需要大量的,并且有一定逻辑结构的数据,希望也能够保存到配置文件中,此时我们可能这样做:将这些数据构造成DataSet,然后使用DataSet.WriteXML直接写成XML文件,读取的时候直接使用DataSet.LoadXML。另外一种方式就是直接操作XML数据,使用XmlDocument

第一种方法虽然是好,因为我们可以想操作数据库表一样操作我们的结构化的数据,可是在某些情况下,总觉得怪怪的。并且增加列等等这些的操作觉得及其难受。特别是我们需要使用这些数据的时候,我们首先要去读文档,了解DataSet中的每个表以及每个字段的含义,所以此方法不可取。

那第二种方法呢,这个更不可取。如果我们增加了某个字段,或者修改了数据的机构,那我们的代码修改起来是在也是比较复杂的事情。

那有什么更好的方式来解决这个问题的呢?

既然微软可以使用App.ConfigWeb.Config,可以使用ComfigManager来对这两个配置文件来进行管理,让我们非常方便地进行使用,那我们为何不可设计自己的ConfigManager呢?

需求:我们这里以菜单结构作为例子来描述我们的想法。

菜单,包括主菜单项,比如系统里面的“文件”,“编辑”等等,包括子菜单,比如“文件”下的“保存”,“另存为”等,子菜单下也包括下级子菜单。总之这是一个完全结构化的数据格式,当然使用菜单来举例主要是这东西我们每天都见到,所以很容易理解,如:

  1. public class Menu
  2. {
  3.     private string _Name;
  4.     private string _Text;
  5.     private string _IconName;
  6.     //...这里可能还有其他你需要变量
  7.     private SubMenus _SubMenus;
  8.     /// <summary>
  9.     /// 注意,一定需要一个无参数的构造函数,否则序列化的时候出错
  10.     /// </summary>
  11.     public Menu()
  12.         : this("""""")
  13.     { }
  14.     public Menu(string name, string text, string iconname)
  15.     {
  16.         this._Name = name;
  17.         this._Text = text;
  18.         this._IconName = iconname;
  19.         this._SubMenus = new SubMenus();
  20.     }
  21.     /// <summary>
  22.     /// 菜单名
  23.     /// </summary>
  24.     [XmlAttribute("Name")]
  25.     public string Name
  26.     {
  27.         get { return this._Name; }
  28.         set { this._Name = value; }
  29.     }
  30.     /// <summary>
  31.     /// 菜单Text
  32.     /// </summary>
  33.     [XmlAttribute("Text")]
  34.     public string Text
  35.     {
  36.         get { return this._Text; }
  37.         set { this._Text = value; }
  38.     }
  39.     /// <summary>
  40.     /// 菜单的图标名
  41.     /// </summary>
  42.     [XmlAttribute("IconName")]
  43.     public string IconName
  44.     {
  45.         get { return this._IconName; }
  46.         set { this._IconName = value; }
  47.     }
  48.     /// <summary>
  49.     /// 子菜单
  50.     /// </summary>
  51.     public SubMenus SubMenus
  52.     {
  53.         get { return this._SubMenus; }
  54.         set { this._SubMenus = value; }
  55.     }
  56. }

好,那我们菜单项包括子菜单,怎么表示呢?

我们使用一个List来保存我们的子菜单,为了更为直观,我们定义一个SubMenus的类,继承于List<Menu>

  1. /// <summary>
  2. /// 子菜单列表
  3. /// </summary>
  4. public class SubMenus : List<Menu>
  5. }

下面我们就来构造我们的菜单MenuStrip。一个MenuStrip中,同样包括多个菜单,比如“文件”“编辑”“视图”等等。

MenuStrip中,我们提供Load()函数,用于加载我们的菜单数据,提供Save()用于保存我们设置好的菜单数据:

  1. public class MenuStrip
  2. {
  3.     //...您需要的其他变量
  4.     private SubMenus _SubMenus;
  5.     public MenuStrip()
  6.     {
  7.         this._SubMenus = new SubMenus();
  8.     }
  9.     public SubMenus SubMenus
  10.     {
  11.         get { return this._SubMenus; }
  12.         set { this._SubMenus = value; }
  13.     }
  14.     /// <summary>
  15.     /// 这里使用Static,方便调用
  16.     /// </summary>
  17.     /// <returns></returns>
  18.     public MenuStrip Load()
  19.     {
  20.         MenuStrip instance = new MenuStrip();
  21.         XmlSerializer xs = new XmlSerializer(typeof(MenuStrip));
  22.         StreamReader sr = new StreamReader(@".../Menu.Config");
  23.         instance = xs.Deserialize(sr) as MenuStrip;
  24.         sr.Close();
  25.         return instance;
  26.     }
  27.     public void Save()
  28.     {
  29.         XmlSerializer xs = new XmlSerializer(typeof(MenuStrip));
  30.         StreamWriter sw = new StreamWriter(@".../Menu.Config");
  31.         xs.Serialize(sw, this);
  32.         sw.Close();
  33.     }
  34. }

测试代码如下:

  1. MenuStrip menustrip = new MenuStrip();
  2. //文件菜单
  3. Menu mnuFile = new Menu("mnuFile""文件(&F)""");
  4. mnuFile.SubMenus.Add(new Menu("mnuNew""新建"""));
  5. mnuFile.SubMenus.Add(new Menu("mnuSave""保存"""));
  6. mnuFile.SubMenus.Add(new Menu("mnuSaveAs""另存为"""));
  7. menustrip.SubMenus.Add(mnuFile);
  8. Menu mnuEdit = new Menu("mnuEdit""编辑(&E)""");
  9. mnuEdit.SubMenus.Add(new Menu("mnuCopy""复制"""));
  10. mnuEdit.SubMenus.Add(new Menu("mnuDelete""删除"""));
  11. mnuEdit.SubMenus.Add(new Menu("mnuCut""剪切"""));
  12. menustrip.SubMenus.Add(mnuEdit);
  13. menustrip.SubMenus.Add(new Menu("mnuView""视图(&V)"""));
  14. menustrip.Save();

上面的代码构造了一个配置文件,保存后结果如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <MenuStrip xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  3.   <SubMenus>
  4.     <Menu Name="mnuFile" Text="文件(&F)" IconName="">
  5.       <SubMenus>
  6.         <Menu Name="mnuNew" Text="新建" IconName="">
  7.           <SubMenus />
  8.         </Menu>
  9.         <Menu Name="mnuSave" Text="保存" IconName="">
  10.           <SubMenus />
  11.         </Menu>
  12.         <Menu Name="mnuSaveAs" Text="另存为" IconName="">
  13.           <SubMenus />
  14.         </Menu>
  15.       </SubMenus>
  16.     </Menu>
  17.     <Menu Name="mnuEdit" Text="编辑(&E)" IconName="">
  18.       <SubMenus>
  19.         <Menu Name="mnuCopy" Text="复制" IconName="">
  20.           <SubMenus />
  21.         </Menu>
  22.         <Menu Name="mnuDelete" Text="删除" IconName="">
  23.           <SubMenus />
  24.         </Menu>
  25.         <Menu Name="mnuCut" Text="剪切" IconName="">
  26.           <SubMenus />
  27.         </Menu>
  28.       </SubMenus>
  29.     </Menu>
  30.     <Menu Name="mnuView" Text="视图(&V)" IconName="">
  31.       <SubMenus />
  32.     </Menu>
  33.   </SubMenus>
  34. </MenuStrip>

您可能会说,这样也不见得很好啊,但是你是否发现,我们就像使用菜单对象一样来操作我们的Menu对象,我们不需要像使用DataSet那样首先要去了解其中每个数据库表的每个字段的含义,也不需要像使用XmlDocument那样去记住每个菜单项的位置。菜单项就是我们的Menu对象,我们可以增加不限级的子菜单,随意遍历我们的菜单等等

 

另,通过这样的方式,可以在我们的应用中设计各种各样易于使用修改和维护的结构。

 

 

相关推荐
小提示: 本资料仅供个人学习参考请勿用于商业用途如有能力请尽量购买正版图书也是对作者支持。 高清PDF文完整版, 被称为“C#圣经”权威著作.    Amazon超级畅销书   全面涵盖C# 3.0用IL深入揭示各语言特性..   深度剖析.NET 3.5平台让你知其然更知其所以然   国内多位微软MVP联手翻译... 本书提供作译者介绍   Andrew Troelsen世界级c#专家微软VisuaI C#MVP。他是著名微软技术咨询企业Intertech合伙人和副总裁该公司客户包括微软、霍尼韦尔、美国宇航局等。他曾为MSDN网站和MacTech网站撰写了有关各种操作系统平台上.NET技术文章并经常业界主要技术会议上发表f演讲和开设技术讲座。除本书外他还撰写了COM and Net interoperabity和Visual Basic NET and the NET Platform An Advanced Guide等十多部NET技术方面著作 本书是c#领域久负盛名经典著作深入全面地叙述了c#编程语言和.net平台核心并以大量示例剖析相关概念。书介绍了c#各种语言构造、.net 2.0类、核心api、公共间语言(cil)、动态程序集和asp.net扩展等内容;同时也介绍了.net 3.0和.net 3.5编程api包括wpf 、wcf和wf 功能;另外还介绍了最新c# 3.0编程语言、linq编程技术、com与.net 互操作性以及平台无关.net开发。   本书由微软c# mvp andrew troelsen编写历经多次修订适合各层次.net开发人员阅读。 第一部分 c#.net平台简介 第1章 net之道  1.1 net之前世界  1.2 net解决方案  1.3 net平台构造块(clr、cts和cls)简介  1.4 其他支持.net编程语言  1.5 net程序集概览  1.6 cts  1.7 cls  1.8 clr  1.9 程序集/命名空间/类型区别  1.10 使用ildasm.exe探索程序集  1.11 使用lutz roederreflector来查看程序集  1.12 部署.net运行库  1.13 net平台无关性  1.14 小结  第2章 构建c#应用程序  2.1 net framework 3.5 sdk作用  2.2 用csc.exe构建c#应用程序  2.3 使用textpad构建.net应用程序  . 2.4 使用notepad++构建.net应用程序  2.5 使用sharpdevelop构建.net应用程序  2.6 使用visual c# 2008 express构建.net应用程序  2.7 使用visual studio 2008构建.net应用程序  2.8 其他.net开发工具  2.9 小结  第二部分 c#核心编程结构 第3章 c#核心编程结构ⅰ  3.1 一个简单c#程序  3.2 有趣题外话:system.environment类其他成员  3.3 system.console类  3.4 系统数据类型和c#简化符号  3.5 system.string数据类型  3.6 窄化和宽化数据类型转换  3.7 c#迭代结构  3.8 条件结构和关系/相等运算符  3.9 小结  第4章 c#核心编程结构ⅱ  4.1 方法和参数修饰符  4.2 成员重载  4.3 c#数组操作  4.4 枚举类型  4.5 结构类型  4.6 值类型和引用类型  4.7 值类型和引用类型:最后细节  4.8 c#可空类型  4.9 小结  第5章 定义封装类类型  5.1 c#类类型  5.2 类构造函数  5.3 this关键字作用  5.4 static关键字  5.5 定义oop支柱  5.6 c#访问修饰符  5.7 第一个支柱:c#封装支持  5.8 常量数据  5.9 只读字段  5.10 c#分部类型  5.11 通过xml生成c#源代码文档  5.12 查看劳动成果  5.13 小结  第6章 继承和多态  6.1 继承基本机制  6.2 回顾visual studio类关系图  6.3 第二个支柱:继承  6.4 包含/委托编程  6.5 第三个支柱:c#多态支持  6.6 基类/派生类转换规则  6.7 超级父类:system.object  6.8 小结  第7章 结构化异常处理  7.1 错误、bug与异常  7.2 net异常处理作用  7.3 最简单例子  7.4 配置异常状态  7.5 系统级异常(system.
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页