在系統開發的過程中,我們總是需要使用配置文件來保存一些我們需要保存的系統參數, 畢竟這是.Net時代,如果再使用注冊表那就顯得復雜了,畢竟操作注冊表的API並不是哪麼容 易理解的。
所以在.net應用程序中,都默認出現一個App.Config(對於 Web應用程序 是Web.Config)我們可以將系統運行所需要的參數采用加密或者明文的方式保存在這個文件 中。但是當我們需要大量的,並且有一定邏輯結構的數據,希望也能夠保存到配置文件中, 此時我們可能這樣做:將這些數據構造成DataSet,然後使用DataSet.WriteXML直接寫成XML 文件,讀取的時候直接使用DataSet.LoadXML。另外一種方式就是直接操作XML數據,使用 XmlDocument。
第一種方法雖然是好,因為我們可以想操作數據庫表一樣操作我們的 結構化的數據,可是在某些情況下,總覺得怪怪的。並且增加列等等這些的操作覺得及其難 受。特別是我們需要使用這些數據的時候,我們首先要去讀文檔,了解DataSet中的每個表以 及每個字段的含義,所以此方法不可取。
那第二種方法呢,這個更不可取。如果我們 增加了某個字段,或者修改了數據的機構,那我們的代碼修改起來是在也是比較復雜的事情 。
那有什麼更好的方式來解決這個問題的呢?
既然微軟可以使用App.Config 和Web.Config,可以使用ComfigManager來對這兩個配置文件來進行管理,讓我們非常方便地 進行使用,那我們為何不可設計自己的ConfigManager呢?
需求:我們這裡以菜單結 構作為例子來描述我們的想法。
菜單,包括主菜單項,比如系統裡面的“文件 ”,“編輯”等等,包括子菜單,比如“文件”下的“保 存”,“另存為”等,子菜單下也包括下級子菜單。總之這是一個完全結構 化的數據格式,當然使用菜單來舉例主要是這東西我們每天都見到,所以很容易理解,如:
public class Menu
{
private string _Name;
private string _Text;
private string _IconName;
//...這裡可能還 有其他你需要變量
private SubMenus _SubMenus;
/// <summary>
/// 注意,一定需要一個無參數的構造函數,否則序列化的時候 出錯
/// </summary>
public Menu()
: this ("", "", "")
{ }
public Menu (string name, string text, string iconname)
{
this._Name = name;
this._Text = text;
this._IconName = iconname;
this._SubMenus = new SubMenus();
}
/// <summary>
/// 菜單名
/// </summary>
[XmlAttribute("Name")]
public string Name
{
get { return this._Name; }
set { this._Name = value; }
}
/// <summary>
/// 菜單Text
/// </summary>
[XmlAttribute("Text")]
public string Text
{
get { return this._Text; }
set { this._Text = value; }
}
/// <summary>
/// 菜單的 圖標名
/// </summary>
[XmlAttribute ("IconName")]
public string IconName
{
get { return this._IconName; }
set { this._IconName = value; }
}
/// <summary>
/// 子菜單
/// </summary>
public SubMenus SubMenus
{
get { return this._SubMenus; }
set { this._SubMenus = value; }
}
}
好,那我們菜單項包括子菜單,怎麼表示呢?
我們使用一個 List來保存我們的子菜單,為了更為直觀,我們定義一個SubMenus的類,繼承於 List<Menu>
/// <summary>
/// 子菜單列表
/// </summary>
public class SubMenus : List<Menu>
{
}
下面我們就來構造我們的菜單MenuStrip。一個MenuStrip中,同樣包括多個 菜單,比如“文件”“編輯”“視圖”等等。
在 MenuStrip中,我們提供Load()函數,用於加載我們的菜單數據,提供Save()用於保存我們設 置好的菜單數據:
public class MenuStrip
{
//...您需要的 其他變量
private SubMenus _SubMenus;
public MenuStrip()
{
this._SubMenus = new SubMenus();
}
public SubMenus SubMenus
{
get { return this._SubMenus; }
set { this._SubMenus = value; }
}
/// <summary>
/// 這裡使用Static,方便調用
/// </summary>
/// <returns></returns>
public MenuStrip Load()
{
MenuStrip instance = new MenuStrip();
XmlSerializer xs = new XmlSerializer(typeof(MenuStrip));
StreamReader sr = new StreamReader(@"...\Menu.Config");
instance = xs.Deserialize(sr) as MenuStrip;
sr.Close();
return instance;
}
public void Save()
{
XmlSerializer xs = new XmlSerializer(typeof(MenuStrip));
StreamWriter sw = new StreamWriter(@"...\Menu.Config");
xs.Serialize(sw, this);
sw.Close();
}
}
測試代碼如下:
MenuStrip menustrip = new MenuStrip();
//文件菜單
Menu mnuFile = new Menu("mnuFile", "文件(&F)", "");
mnuFile.SubMenus.Add(new Menu("mnuNew", "新建 ", ""));
mnuFile.SubMenus.Add(new Menu("mnuSave", "保存", ""));
mnuFile.SubMenus.Add(new Menu ("mnuSaveAs", "另存為", ""));
menustrip.SubMenus.Add(mnuFile);
Menu mnuEdit = new Menu ("mnuEdit", "編輯(&E)", "");
mnuEdit.SubMenus.Add(new Menu("mnuCopy", "復制", ""));
mnuEdit.SubMenus.Add(new Menu("mnuDelete", " 刪除", ""));
mnuEdit.SubMenus.Add(new Menu ("mnuCut", "剪切", ""));
menustrip.SubMenus.Add(mnuEdit);
menustrip.SubMenus.Add(new Menu ("mnuView", "視圖(&V)", ""));
menustrip.Save();
上面的代碼構造了一個配置文件,保存後結果如下:
<?xml version="1.0" encoding="utf-8"?>
<MenuStrip xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SubMenus>
<Menu Name="mnuFile" Text="文件 (&F)" IconName="">
<SubMenus>
<Menu Name="mnuNew" Text="新建" IconName="">
<SubMenus />
</Menu>
<Menu Name="mnuSave" Text="保存 " IconName="">
<SubMenus />
</Menu>
<Menu Name="mnuSaveAs" Text="另存為 " IconName="">
<SubMenus />
</Menu>
</SubMenus>
</Menu>
<Menu Name="mnuEdit" Text="編輯(&E)" IconName="">
<SubMenus>
<Menu Name="mnuCopy" Text="復制" IconName="">
<SubMenus />
</Menu>
<Menu Name="mnuDelete" Text="刪除" IconName="">
<SubMenus />
</Menu>
<Menu Name="mnuCut" Text="剪切" IconName="">
<SubMenus />
</Menu>
</SubMenus>
</Menu>
<Menu Name="mnuView" Text="視圖(&V)" IconName="">
<SubMenus />
</Menu>
</SubMenus>
</MenuStrip>
您可能會說,這樣也不見 得很好啊,但是你是否發現,我們就像使用菜單對象一樣來操作我們的Menu對象,我們不需 要像使用DataSet那樣首先要去了解其中每個數據庫表的每個字段的含義,也不需要像使用 XmlDocument那樣去記住每個菜單項的位置。菜單項就是我們的Menu對象,我們可以增加不限 級的子菜單,隨意遍歷我們的菜單等等。
另,通過這樣的方式,可以在我們的應用中 設計各種各樣易於使用修改和維護的結構。