asp.net SAF 中緩存服務(wù)的實(shí)現(xiàn)第3/5頁(yè)
Cache類(lèi)還包含兩個(gè)私有方法。PreparePath()用于對(duì)輸入的Xpath進(jìn)行格式化,使其以構(gòu)造函數(shù)中創(chuàng)建的根節(jié)點(diǎn)("Cache")作為根結(jié)點(diǎn)(這樣做是可以使你在添加/獲取對(duì)象時(shí)免去寫(xiě)根結(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,通過(guò)調(diào)用ICacheStrategy.AddItem()方法來(lái)完成,并將Hashtable的Key設(shè)置為GUID。
NOTE: 為了說(shuō)明方便,這里有一個(gè)我對(duì)一類(lèi)結(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 來(lái)說(shuō),它的組結(jié)點(diǎn)就是“/Cache/BookStore”,而 Book是它的葉結(jié)點(diǎn)。
下面是AddItem()方法的完整代碼:
// 添加對(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 ,用來(lái)映射 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文檔樹(shù)中刪除結(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)文章
Excel自定義關(guān)閉按鈕實(shí)現(xiàn)代碼
這篇文章主要介紹了Excel自定義關(guān)閉按鈕實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
.net開(kāi)發(fā)微信公眾平臺(tái)實(shí)例教程
這篇文章主要介紹了.net開(kāi)發(fā)微信公眾平臺(tái)的方法,對(duì)微信公眾平臺(tái)開(kāi)發(fā)的原理與相應(yīng)的.net實(shí)現(xiàn)方法都做了較為詳細(xì)的講述,非常實(shí)用,需要的朋友可以參考下2014-10-10
.Net 調(diào)用存儲(chǔ)過(guò)程取到return的返回值
存儲(chǔ)過(guò)程只能返回 int 類(lèi)型,如果返回一個(gè)字符串 ,將會(huì)報(bào)類(lèi)型轉(zhuǎn)化錯(cuò)誤,下面以示例介紹下如何取到return的值,需要的朋友可以參考下2014-08-08
ASP.NET C#生成下拉列表樹(shù)實(shí)現(xiàn)代碼
下拉列表樹(shù)很方便且時(shí)尚的一個(gè)導(dǎo)航,貌似很多的朋友都想實(shí)現(xiàn)這樣一個(gè)列表樹(shù),本文將滿足你們的設(shè)想,通過(guò)本文你們可以學(xué)到如何使用c#生成下拉列表樹(shù),感興趣的你可不要錯(cuò)過(guò)了啊2013-02-02
ASP.NET數(shù)據(jù)綁定之DataList控件
這篇文章主要為大家介紹了ASP.NET數(shù)據(jù)綁定中的DataList控件,DataList控件以表的形式呈現(xiàn)數(shù)據(jù),通過(guò)該控件,您可以使用不同的布局來(lái)顯示數(shù)據(jù)記錄,對(duì)DataList控件感興趣的小伙伴們可以參考一下2016-01-01
ASP.NET Core 3.0輕量級(jí)角色API控制授權(quán)庫(kù)
這篇文章介紹了ASP.NET Core 3.0輕量級(jí)角色API控制授權(quán)庫(kù),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01
ASP.NET Core中如何實(shí)現(xiàn)重定向詳解
這篇文章主要給大家介紹了關(guān)于ASP.NET Core中如何實(shí)現(xiàn)重定向的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
用Html5與Asp.net MVC上傳多個(gè)文件的實(shí)現(xiàn)代碼
Html 5 的有一些File API,對(duì)Form表單增強(qiáng)的特性,讓我們輕松支持多文件上傳,看下面的Html片斷代碼2012-08-08
.NET 中的裝箱與拆箱實(shí)現(xiàn)過(guò)程
本文分別介紹裝箱(boxing)與拆箱(unboxing)的實(shí)現(xiàn)過(guò)程,感興趣的朋友可以了解下2013-01-01
ASP.NET DataTable去掉重復(fù)行的2種方法
這篇文章主要介紹了ASP.NET DataTable去掉重復(fù)行的2種方法,本文直接給出去重代碼,需要的朋友可以參考下2015-02-02

