asp.net SAF 中緩存服務的實現第3/5頁
更新時間:2008年08月08日 21:28:49 作者:
對緩存的興趣源于張子陽寫的一篇文章《SAF 中緩存服務的實現》中的一個例子:
Cache類還包含兩個私有方法。PreparePath()用于對輸入的Xpath進行格式化,使其以構造函數中創(chuàng)建的根節(jié)點("Cache")作為根結點(這樣做是可以使你在添加/獲取對象時免去寫根結點的麻煩);CreateNode() 用于根據XPath逐層深入地創(chuàng)建Xml結點。 C#復制代碼
// 根據 XPath 創(chuàng)建一個結點
private XmlNode CreateNode(string xpath) {
string[] xpathArray = xpath.Split('/');
string nodePath = "";
// 父節(jié)點初始化
XmlNode parentNode = (XmlNode)rootMap;
// 逐層深入 XPath 各層級,如果結點不存在則創(chuàng)建
// 比如 /DvdStore/Dvd/NoOneLivesForever
for (int i = 1; i < xpathArray.Length; i++) {
XmlNode node = rootMap.SelectSingleNode(nodePath + "/" + xpathArray[i]);
if (node == null) {
XmlElement newElement = rootMap.OwnerDocument.CreateElement(xpathArray[i]); // 創(chuàng)建結點
parentNode.AppendChild(newElement);
}
// 創(chuàng)建新路徑,更新父節(jié)點,進入下一級
nodePath = nodePath + "/" + xpathArray[i];
parentNode = rootMap.SelectSingleNode(nodePath);
}
return parentNode;
}
// 構建 XPath,使其以 /Cache 為根結點,并清除多于的"/"字符
private string PrepareXPath(string xpath) {
string[] xpathArray = xpath.Split('/');
xpath = "/Cache"; // 這里的名稱需與構造函數中創(chuàng)建的根結點名稱對應
foreach (string s in xpathArray) {
if (s != "") {
xpath += "/" + s;
}
}
return xpath;
}
AddItem()方法用于向緩存中添加對象,包括了下面幾個步驟:
1、根據輸入的XPath判斷到達 葉結點 的路徑是否已經存在,如果不存在,調用上面的CreateNode()方法,逐層創(chuàng)建結點。
2、生成GUID,在組結點下創(chuàng)建 XmlNode 葉結點,為葉結點添加屬性Key,并將值設為GUID。
3、將對象保存至實際的位置,默認實現是一個Hashtable,通過調用ICacheStrategy.AddItem()方法來完成,并將Hashtable的Key設置為GUID。
NOTE: 為了說明方便,這里有一個我對一類結點的命名--“組結點”。假設有XPath路徑:/Cache/BookStore/Book/Title,那么/Cache/BookStore/Book即為“組結點”,稱其為“組結點”,是因為其下可包含多個葉結點,比如 /Cache/BookStore/Book/Author 包含了葉結點 Author;而/Cache/BookStore/Book/Title 中的Title為葉結點,GUID存儲在葉結點的屬性中。需要注意 組結點 和 葉結點是相對的,對于路徑 /Cache/BookStore/Book 來說,它的組結點就是“/Cache/BookStore”,而 Book是它的葉結點。
下面是AddItem()方法的完整代碼:
復制代碼 代碼如下:
// 添加對象,對象實際上還是添加到ICacheStrategy指定的存儲位置,
// 動態(tài)創(chuàng)建的 Xml 結點僅保存了對象的Id(key),用于映射兩者間的關系
public virtual void AddItem(string xpath, object obj) {
// 獲取 Xpath,例如 /Cache/BookStore/Book/Title
string newXpath = PrepareXPath(xpath);
int separator = newXpath.LastIndexOf("/");
// 獲取組結點的層疊順序 ,例如 /Cache/BookStore/Book
string group = newXpath.Substring(0, separator);
// 獲取葉結點名稱,例如 Title
string element = newXpath.Substring(separator + 1);
// 獲取組結點
XmlNode groupNode = rootMap.SelectSingleNode(group);
// 如果組結點不存在,創(chuàng)建之
if (groupNode == null) {
lock (this) {
groupNode = CreateNode(group);
}
}
// 創(chuàng)建一個唯一的 key ,用來映射 Xml 和對象的主鍵
string key = Guid.NewGuid().ToString();
// 創(chuàng)建一個新結點
XmlElement objectElement = rootMap.OwnerDocument.CreateElement(element);
// 創(chuàng)建結點屬性 key
XmlAttribute objectAttribute = rootMap.OwnerDocument.CreateAttribute("key");
// 設置屬性值為 剛才生成的 Guid
objectAttribute.Value = key;
// 將屬性添加到結點
objectElement.Attributes.Append(objectAttribute);
// 將結點添加到 groupNode 下面(groupNode為Xpath的層次部分)
groupNode.AppendChild(objectElement);
// 將 key 和 對象添加到實際的存儲位置,比如Hashtable
cacheStrategy.AddItem(key, obj);
}
RemoveItem()則用于從緩存中刪除對象,它也包含了兩個步驟:1、先從Xml文檔樹中刪除結點;2、再從實際的存儲位置(Hashtable)中刪除對象。這里需要注意的是:如果XPath指定的是一個葉結點,那么直接刪除該結點;如果XPath指定的是組結點,那么需要刪除組結點下的所有結點。代碼如下:
C#復制代碼
// 根據 XPath 刪除對象
public virtual void RemoveItem(string xpath) {
xpath = PrepareXPath(xpath);
XmlNode result = rootMap.SelectSingleNode(xpath);
string key; // 對象的Id
// 如果 result 是一個組結點(含有子結點)
if (result.HasChildNodes) {
// 選擇所有包含有key屬性的的結點
XmlNodeList nodeList = result.SelectNodes("descendant::*[@key]");
foreach (XmlNode node in nodeList) {
key = node.Attributes["key"].Value;
// 從 Xml 文檔中刪除結點
node.ParentNode.RemoveChild(node);
// 從實際存儲中刪除結點
cacheStrategy.RemoveItem(key);
}
} else { // 如果 result 是一個葉結點(不含子結點)
key = result.Attributes["key"].Value;
result.ParentNode.RemoveChild(result);
cacheStrategy.RemoveItem(key);
}
}
相關文章
ASP.NET實現TreeView的XML數據源綁定實例代碼
這篇文章介紹了ASP.NET實現TreeView的XML數據源綁定實例代碼,有需要的朋友可以參考一下2013-11-11ASP.NET堆和棧二之值類型和引用類型的參數傳遞和內存分配
這篇文章介紹了ASP.NET堆和棧中值類型和引用類型的參數傳遞和內存分配,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08如何在ASP.NET Core中給上傳圖片功能添加水印實例代碼
這篇文章主要給大家介紹了關于如何在ASP.NET Core中給上傳圖片功能添加水印的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-02-02asp.net core webapi項目配置全局路由的方法示例
這篇文章主要介紹了asp.net core webapi項目配置全局路由的方法示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09