高訪問、低更新場景下緩存至關重要。PetShop 4.0 採用工廠模式+配置驅動實現靈活緩存依賴管理,核心利用 .NET 2.0 SqlCacheDependency 與 AggregateCacheDependency。
PetShop.ICacheDependency // 接口定義 PetShop.TableCacheDependency // 表依賴實現 (抽象基類 + 具體表類) PetShop.CacheDependencyFactory // 工廠創建與門面 PetShop.Web // Web 層代理調用
public interface IPetShopCacheDependency
{
AggregateCacheDependency GetDependency(); // 無參數,返回聚合依賴
}
AggregateCacheDependency (2.0 新增) 組合多個 CacheDependency。
protected TableDependency(string configKey)
{
string dbName = ConfigurationManager.AppSettings["CacheDatabaseName"];
string tableConfig = ConfigurationManager.AppSettings[configKey];
string[] tables = tableConfig.Split(',');
foreach (string tableName in tables)
dependency.Add(new SqlCacheDependency(dbName, tableName));
}
CacheDatabaseName 與表依賴配置鍵SqlCacheDependency 數組加入聚合依賴SqlCacheDependency 建立緩存項與 SQL Server 表變更的綁定
// Category 依賴 Category 表
public class Category : TableDependency
{ public Category() : base("CategoryTableDependency") {} }
// Product 依賴 Product, Category 表
public class Product : TableDependency
{ public Product() : base("ProductTableDependency") {} }
// Item 依賴 Product, Category, Item 表
public class Item : TableDependency
{ public Item() : base("ItemTableDependency") {} }
<!-- 依賴程序集:SQL Server 使用 TableCacheDependency,Oracle 留空 -->
<add key="CacheDependencyAssembly" value="PetShop.TableCacheDependency"/>
<add key="CacheDatabaseName" value="MSPetShop4"/>
<add key="CategoryTableDependency" value="Category"/>
<add key="ProductTableDependency" value="Product,Category"/>
<add key="ItemTableDependency" value="Product,Category,Item"/>
<add key="CategoryCacheDuration" value="1"/> <!-- 小時 -->
private static IPetShopCacheDependency LoadInstance(string className)
{
string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
string fullyQualifiedClass = path + "." + className;
return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
}
反射創建實例,三個公共方法分別返回 Category/Product/Item 依賴。
AggregateCacheDependencyCategoryDataProxy、ItemDataProxy、ProductDataProxy 分別調用門面獲取依賴。
if (data == null)
{
int cacheDuration = int.Parse(ConfigurationManager.AppSettings["CategoryCacheDuration"]);
data = category.GetCategory(categoryId).Name; // 業務層獲取數據
AggregateCacheDependency cd = DependencyFacade.GetCategoryDependency();
HttpRuntime.Cache.Add(cacheKey, data, cd,
DateTime.Now.AddHours(cacheDuration),
Cache.NoSlidingExpiration,
CacheItemPriority.High, null);
}
| 策略 | 機制 | PetShop 採用 |
|---|---|---|
| 主動檢查 | 每次訪問判斷緩存是否存在,無則重載 | ✓ 採用 |
| 回調重建 | CacheItemRemovedCallback 失效時自動重建 | 未採用 |