asp.net SAF 中緩存服務(wù)的實現(xiàn)
更新時間:2008年08月08日 21:28:49 作者:
對緩存的興趣源于張子陽寫的一篇文章《SAF 中緩存服務(wù)的實現(xiàn)》中的一個例子:
全部代碼:
ICacheStrategy.cs
復(fù)制代碼 代碼如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace CacheService {
// 定義如何添加、獲取、刪除欲進行緩存的對象
public interface ICacheStrategy {
// 添加對象
void AddItem(string key, object obj);
// 獲取對象
object GetItem(string key);
// 刪除對象
void RemoveItem(string key);
}
public class DefaultCacheStrategy : ICacheStrategy {
private Hashtable objectStore;
public DefaultCacheStrategy() {
objectStore = new Hashtable();
}
public void AddItem(string key, object obj) {
objectStore.Add(key, obj);
}
public object GetItem(string key) {
return objectStore[key];
}
public void RemoveItem(string key) {
objectStore.Remove(key);
}
}
}
Cache.cs
復(fù)制代碼 代碼如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections;
namespace CacheService {
// 使用樹形結(jié)構(gòu)來存儲對象,有別于Hashtable的平板式結(jié)構(gòu)
// 通過 XPath 來進行對象獲取
public class Cache {
private XmlElement rootMap; // 動態(tài)構(gòu)建的 Xml文檔 的根結(jié)點
private ICacheStrategy cacheStrategy;
public static readonly Cache Instance = new Cache(); // 實現(xiàn)Singleton模式
private XmlDocument doc = new XmlDocument(); // 構(gòu)建 Xml文檔
// 私有構(gòu)造函數(shù),用來實現(xiàn)Singleton模式
private Cache() {
// 這里應(yīng)用了Strategy模式。
// 改進:可以將使用何種Strategy定義到app.config中,然后使用反射來動態(tài)創(chuàng)建類型
cacheStrategy = new DefaultCacheStrategy();
// 創(chuàng)建文檔根結(jié)點,用于映射 實際的數(shù)據(jù)存儲(例如Hashtable) 和 Xml文檔
rootMap = doc.CreateElement("Cache");
// 添加根結(jié)點
doc.AppendChild(rootMap);
}
// 根據(jù) XPath 獲取對象
// 先根據(jù)Xpath獲得對象的Key,然后再根據(jù)Key獲取實際對象
public virtual object GetItem(string xpath) {
object obj = null;
xpath = PrepareXPath(xpath);
XmlNode node = rootMap.SelectSingleNode(xpath);
if (node != null) {
// 獲取對象的Key
string key = node.Attributes["key"].Value;
// 獲取實際對象
obj = cacheStrategy.GetItem(key);
}
return obj;
}
// 獲取一組對象,此時xpath為一個組結(jié)點
public virtual object[] GetList(string xpath) {
xpath = PrepareXPath(xpath);
XmlNode group = rootMap.SelectSingleNode(xpath);
// 獲取該結(jié)點下的所有子結(jié)點(使用[@key]確保子結(jié)點一定包含key屬性)
XmlNodeList results = group.SelectNodes(xpath + "/*[@key]");
ArrayList objects = new ArrayList();
string key;
foreach (XmlNode result in results) {
key = result.Attributes["key"].Value;
Object obj = cacheStrategy.GetItem(key);
objects.Add(obj);
}
return (object[])objects.ToArray(typeof(object));
}
// 添加對象,對象實際上還是添加到ICacheStrategy指定的存儲位置,
// 動態(tài)創(chuàng)建的 Xml 結(jié)點僅保存了對象的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é)點的層疊順序 ,例如 /Cache/BookStore/Book
string group = newXpath.Substring(0, separator);
// 獲取葉結(jié)點名稱,例如 Title
string element = newXpath.Substring(separator + 1);
// 獲取組結(jié)點
XmlNode groupNode = rootMap.SelectSingleNode(group);
// 如果組結(jié)點不存在,創(chuàng)建之
if (groupNode == null) {
lock (this) {
groupNode = CreateNode(group);
}
}
// 創(chuàng)建一個唯一的 key ,用來映射 Xml 和對象的主鍵
string key = Guid.NewGuid().ToString();
// 創(chuàng)建一個新結(jié)點
XmlElement objectElement = rootMap.OwnerDocument.CreateElement(element);
// 創(chuàng)建結(jié)點屬性 key
XmlAttribute objectAttribute = rootMap.OwnerDocument.CreateAttribute("key");
// 設(shè)置屬性值為 剛才生成的 Guid
objectAttribute.Value = key;
// 將屬性添加到結(jié)點
objectElement.Attributes.Append(objectAttribute);
// 將結(jié)點添加到 groupNode 下面(groupNode為Xpath的層次部分)
groupNode.AppendChild(objectElement);
// 將 key 和 對象添加到實際的存儲位置,比如Hashtable
cacheStrategy.AddItem(key, obj);
}
// 根據(jù) XPath 刪除對象
public virtual void RemoveItem(string xpath) {
xpath = PrepareXPath(xpath);
XmlNode result = rootMap.SelectSingleNode(xpath);
string key; // 對象的Id
// 如果 result 是一個組結(jié)點(含有子結(jié)點)
if (result.HasChildNodes) {
// 選擇所有包含有key屬性的的結(jié)點
XmlNodeList nodeList = result.SelectNodes("descendant::*[@key]");
foreach (XmlNode node in nodeList) {
key = node.Attributes["key"].Value;
// 從 Xml 文檔中刪除結(jié)點
node.ParentNode.RemoveChild(node);
// 從實際存儲中刪除結(jié)點
cacheStrategy.RemoveItem(key);
}
} else { // 如果 result 是一個葉結(jié)點(不含子結(jié)點)
key = result.Attributes["key"].Value;
result.ParentNode.RemoveChild(result);
cacheStrategy.RemoveItem(key);
}
}
// 根據(jù) XPath 創(chuàng)建一個結(jié)點
private XmlNode CreateNode(string xpath) {
string[] xpathArray = xpath.Split('/');
string nodePath = "";
// 父節(jié)點初始化
XmlNode parentNode = (XmlNode)rootMap;
// 逐層深入 XPath 各層級,如果結(jié)點不存在則創(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é)點
parentNode.AppendChild(newElement);
}
// 創(chuàng)建新路徑,更新父節(jié)點,進入下一級
nodePath = nodePath + "/" + xpathArray[i];
parentNode = rootMap.SelectSingleNode(nodePath);
}
return parentNode;
}
// 構(gòu)建 XPath,使其以 /Cache 為根結(jié)點,并清除多于的"/"字符
private string PrepareXPath(string xpath) {
string[] xpathArray = xpath.Split('/');
xpath = "/Cache"; // 這里的名稱需與構(gòu)造函數(shù)中創(chuàng)建的根結(jié)點名稱對應(yīng)
foreach (string s in xpathArray) {
if (s != "") {
xpath += "/" + s;
}
}
return xpath;
}
}
}
相關(guān)文章
ASP.NET實現(xiàn)TreeView的XML數(shù)據(jù)源綁定實例代碼
這篇文章介紹了ASP.NET實現(xiàn)TreeView的XML數(shù)據(jù)源綁定實例代碼,有需要的朋友可以參考一下2013-11-11ASP.NET堆和棧二之值類型和引用類型的參數(shù)傳遞和內(nèi)存分配
這篇文章介紹了ASP.NET堆和棧中值類型和引用類型的參數(shù)傳遞和內(nèi)存分配,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08如何在ASP.NET Core中給上傳圖片功能添加水印實例代碼
這篇文章主要給大家介紹了關(guān)于如何在ASP.NET Core中給上傳圖片功能添加水印的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02asp.net core webapi項目配置全局路由的方法示例
這篇文章主要介紹了asp.net core webapi項目配置全局路由的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09