asp.net SAF 中緩存服務(wù)的實(shí)現(xiàn)第3/5頁(yè)
更新時(shí)間:2008年08月08日 21:28:49 作者:
對(duì)緩存的興趣源于張子陽(yáng)寫的一篇文章《SAF 中緩存服務(wù)的實(shí)現(xiàn)》中的一個(gè)例子:
Cache類還包含兩個(gè)私有方法。PreparePath()用于對(duì)輸入的Xpath進(jìn)行格式化,使其以構(gòu)造函數(shù)中創(chuàng)建的根節(jié)點(diǎn)("Cache")作為根結(jié)點(diǎn)(這樣做是可以使你在添加/獲取對(duì)象時(shí)免去寫根結(jié)點(diǎn)的麻煩);CreateNode() 用于根據(jù)XPath逐層深入地創(chuàng)建Xml結(jié)點(diǎn)。 C#復(fù)制代碼
// 根據(jù) XPath 創(chuàng)建一個(gè)結(jié)點(diǎn)
private XmlNode CreateNode(string xpath) {
string[] xpathArray = xpath.Split('/');
string nodePath = "";
// 父節(jié)點(diǎn)初始化
XmlNode parentNode = (XmlNode)rootMap;
// 逐層深入 XPath 各層級(jí),如果結(jié)點(diǎn)不存在則創(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)建結(jié)點(diǎn)
parentNode.AppendChild(newElement);
}
// 創(chuàng)建新路徑,更新父節(jié)點(diǎn),進(jìn)入下一級(jí)
nodePath = nodePath + "/" + xpathArray[i];
parentNode = rootMap.SelectSingleNode(nodePath);
}
return parentNode;
}
// 構(gòu)建 XPath,使其以 /Cache 為根結(jié)點(diǎn),并清除多于的"/"字符
private string PrepareXPath(string xpath) {
string[] xpathArray = xpath.Split('/');
xpath = "/Cache"; // 這里的名稱需與構(gòu)造函數(shù)中創(chuàng)建的根結(jié)點(diǎn)名稱對(duì)應(yīng)
foreach (string s in xpathArray) {
if (s != "") {
xpath += "/" + s;
}
}
return xpath;
}
AddItem()方法用于向緩存中添加對(duì)象,包括了下面幾個(gè)步驟:
1、根據(jù)輸入的XPath判斷到達(dá) 葉結(jié)點(diǎn) 的路徑是否已經(jīng)存在,如果不存在,調(diào)用上面的CreateNode()方法,逐層創(chuàng)建結(jié)點(diǎn)。
2、生成GUID,在組結(jié)點(diǎn)下創(chuàng)建 XmlNode 葉結(jié)點(diǎn),為葉結(jié)點(diǎn)添加屬性Key,并將值設(shè)為GUID。
3、將對(duì)象保存至實(shí)際的位置,默認(rèn)實(shí)現(xiàn)是一個(gè)Hashtable,通過調(diào)用ICacheStrategy.AddItem()方法來完成,并將Hashtable的Key設(shè)置為GUID。
NOTE: 為了說明方便,這里有一個(gè)我對(duì)一類結(jié)點(diǎn)的命名--“組結(jié)點(diǎn)”。假設(shè)有XPath路徑:/Cache/BookStore/Book/Title,那么/Cache/BookStore/Book即為“組結(jié)點(diǎn)”,稱其為“組結(jié)點(diǎn)”,是因?yàn)槠湎驴砂鄠€(gè)葉結(jié)點(diǎn),比如 /Cache/BookStore/Book/Author 包含了葉結(jié)點(diǎn) Author;而/Cache/BookStore/Book/Title 中的Title為葉結(jié)點(diǎn),GUID存儲(chǔ)在葉結(jié)點(diǎn)的屬性中。需要注意 組結(jié)點(diǎn) 和 葉結(jié)點(diǎn)是相對(duì)的,對(duì)于路徑 /Cache/BookStore/Book 來說,它的組結(jié)點(diǎn)就是“/Cache/BookStore”,而 Book是它的葉結(jié)點(diǎn)。
下面是AddItem()方法的完整代碼:
復(fù)制代碼 代碼如下:
// 添加對(duì)象,對(duì)象實(shí)際上還是添加到ICacheStrategy指定的存儲(chǔ)位置,
// 動(dòng)態(tài)創(chuàng)建的 Xml 結(jié)點(diǎn)僅保存了對(duì)象的Id(key),用于映射兩者間的關(guān)系
public virtual void AddItem(string xpath, object obj) {
// 獲取 Xpath,例如 /Cache/BookStore/Book/Title
string newXpath = PrepareXPath(xpath);
int separator = newXpath.LastIndexOf("/");
// 獲取組結(jié)點(diǎn)的層疊順序 ,例如 /Cache/BookStore/Book
string group = newXpath.Substring(0, separator);
// 獲取葉結(jié)點(diǎn)名稱,例如 Title
string element = newXpath.Substring(separator + 1);
// 獲取組結(jié)點(diǎn)
XmlNode groupNode = rootMap.SelectSingleNode(group);
// 如果組結(jié)點(diǎn)不存在,創(chuàng)建之
if (groupNode == null) {
lock (this) {
groupNode = CreateNode(group);
}
}
// 創(chuàng)建一個(gè)唯一的 key ,用來映射 Xml 和對(duì)象的主鍵
string key = Guid.NewGuid().ToString();
// 創(chuàng)建一個(gè)新結(jié)點(diǎn)
XmlElement objectElement = rootMap.OwnerDocument.CreateElement(element);
// 創(chuàng)建結(jié)點(diǎn)屬性 key
XmlAttribute objectAttribute = rootMap.OwnerDocument.CreateAttribute("key");
// 設(shè)置屬性值為 剛才生成的 Guid
objectAttribute.Value = key;
// 將屬性添加到結(jié)點(diǎn)
objectElement.Attributes.Append(objectAttribute);
// 將結(jié)點(diǎn)添加到 groupNode 下面(groupNode為Xpath的層次部分)
groupNode.AppendChild(objectElement);
// 將 key 和 對(duì)象添加到實(shí)際的存儲(chǔ)位置,比如Hashtable
cacheStrategy.AddItem(key, obj);
}
RemoveItem()則用于從緩存中刪除對(duì)象,它也包含了兩個(gè)步驟:1、先從Xml文檔樹中刪除結(jié)點(diǎn);2、再?gòu)膶?shí)際的存儲(chǔ)位置(Hashtable)中刪除對(duì)象。這里需要注意的是:如果XPath指定的是一個(gè)葉結(jié)點(diǎn),那么直接刪除該結(jié)點(diǎn);如果XPath指定的是組結(jié)點(diǎn),那么需要?jiǎng)h除組結(jié)點(diǎn)下的所有結(jié)點(diǎn)。代碼如下:
C#復(fù)制代碼
// 根據(jù) XPath 刪除對(duì)象
public virtual void RemoveItem(string xpath) {
xpath = PrepareXPath(xpath);
XmlNode result = rootMap.SelectSingleNode(xpath);
string key; // 對(duì)象的Id
// 如果 result 是一個(gè)組結(jié)點(diǎn)(含有子結(jié)點(diǎn))
if (result.HasChildNodes) {
// 選擇所有包含有key屬性的的結(jié)點(diǎn)
XmlNodeList nodeList = result.SelectNodes("descendant::*[@key]");
foreach (XmlNode node in nodeList) {
key = node.Attributes["key"].Value;
// 從 Xml 文檔中刪除結(jié)點(diǎn)
node.ParentNode.RemoveChild(node);
// 從實(shí)際存儲(chǔ)中刪除結(jié)點(diǎn)
cacheStrategy.RemoveItem(key);
}
} else { // 如果 result 是一個(gè)葉結(jié)點(diǎn)(不含子結(jié)點(diǎn))
key = result.Attributes["key"].Value;
result.ParentNode.RemoveChild(result);
cacheStrategy.RemoveItem(key);
}
}
相關(guān)文章
ASP.NET實(shí)現(xiàn)TreeView的XML數(shù)據(jù)源綁定實(shí)例代碼
這篇文章介紹了ASP.NET實(shí)現(xiàn)TreeView的XML數(shù)據(jù)源綁定實(shí)例代碼,有需要的朋友可以參考一下2013-11-11ASP.NET堆和棧二之值類型和引用類型的參數(shù)傳遞和內(nèi)存分配
這篇文章介紹了ASP.NET堆和棧中值類型和引用類型的參數(shù)傳遞和內(nèi)存分配,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08如何ASP.NET Core Razor中處理Ajax請(qǐng)求
本篇技術(shù)文章主要給大家講述了如何ASP.NET Core Razor中處理Ajax請(qǐng)求這方面的知識(shí)點(diǎn),有興趣的朋友參考下。2018-01-01ASP.NET搭配Ajax實(shí)現(xiàn)搜索提示功能
為了更好的用戶體驗(yàn),不論是桌面軟件還是網(wǎng)站,在搜索查詢的輸入中都會(huì)加入提示功能,就像百度搜索一樣!今天筆者就ASP.NET編程介紹一下如何利用Ajax來實(shí)現(xiàn)搜索信息提示功能。2015-09-09asp.net+js實(shí)時(shí)奧運(yùn)金牌榜代碼
運(yùn)期間,公司交給我一個(gè)任務(wù),在公司主頁(yè)上放上奧運(yùn)金牌榜的排名,之前的實(shí)現(xiàn)方式是采用ajax2008-09-09如何在ASP.NET Core中給上傳圖片功能添加水印實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于如何在ASP.NET Core中給上傳圖片功能添加水印的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02asp.net core webapi項(xiàng)目配置全局路由的方法示例
這篇文章主要介紹了asp.net core webapi項(xiàng)目配置全局路由的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09