petshop学习笔记(4)
来源:互联网 发布:上海一条网络 编辑:程序博客网 时间:2024/06/06 01:00
回到Products.aspx的代码分析,前面我的2章都分析了products.aspx这个例子里包括的三层架构学习及工厂模式的原理,接下来就是要学学NET2.0的缓存技术。
上章还留下了最后一点没有去写。就是用户控件ProductsControl.ascx.cs,先看看代码
protected void Page_Load(object sender, EventArgs e) {
this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();
}
解读一下 this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();
一、this.CachePolicy.Dependency部份
this.CachePolicy.Dependency用帮助文件里解析为:”获取或设置与缓存的用户控件输出关联的 CacheDependency 类的实例。”这句话什么意思呢?“与缓存的用户控件输出关联的…”,返回到ProductsControl.ascx,看页面最上面有三段代码
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ProductsControl.ascx.cs" Inherits="PetShop.Web.ProductsControl" EnableViewState="false" %>
<%@ Register TagPrefix="PetShopControl" Namespace="PetShop.Web" %>
<%@ OutputCache Duration="100000" VaryByParam="page;categoryId" %>
原来这个用户控件ProductsControl.ascx这个控件设置了缓存
<%@ OutputCache Duration="100000" VaryByParam="page;categoryId" %>ASP.NET 页的缓存的方法是在页中使用 @ OutputCache 指令,
Duration:设置缓存到期时间,单位:秒。
VaryByParam:可用来使缓存输出因查询字符串而异,多个查询字符用分号隔开。
VaryByControl:可用来使缓存输出因控制值而异。
VaryByHeader:可用来使缓存输出因请求的 HTTP 标头而异。
VaryByCustom:可用来使缓存输出因浏览器类型或您定义的自定义字符串而异。
CacheProfile:结合配置文件使用。
Location:设置页的可缓存性,值有Any,Client,Downstream,None,Server,ServerAndClient。
这里的设置了缓存输出的参数为page及categoryID。(这里有些不明白,为什么他还要用个page?他只需要输出缓存给categoryID这个控件上就行了)
二、DependencyFacade.GetProductDependency()部份
DependencyFacade.GetProductDependency部份我们将开始分析PetShop是如何使用缓存技术的。先追踪一下DependencyFacade类,这个类放在CacheDependencyFactory项目里,根据这个项目名称我们得知,这个是专门放置缓存依赖工厂类。看来又是一个工厂模式的设计了,PetShop在看之前就听说了很了大量了工厂设计模式,看来可以好好学习了。先看这个DependencyFacade到底是在写什么东西?
DependencyFacade.cs代码:
public static class DependencyFacade {
private static readonly string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
public static AggregateCacheDependency GetCategoryDependency() {
if (!string.IsNullOrEmpty(path))
return DependencyAccess.CreateCategoryDependency().GetDependency();
else
return null;
}
public static AggregateCacheDependency GetProductDependency() {
if (!string.IsNullOrEmpty(path))
return DependencyAccess.CreateProductDependency().GetDependency();
else
return null;
}
public static AggregateCacheDependency GetItemDependency() {
if (!string.IsNullOrEmpty(path))
return DependencyAccess.CreateItemDependency().GetDependency();
else
return null;
}
}
这个类里有三个方法都有同一个返回类型为AggregateCacheDependency的东西。在这里我并不太清楚AggregateCacheDependency到底是什么东西?因为1.1原来是没有这个东西的,去看了帮助文档才知道原来这个是2.0新增的。解析为:“组合 ASP.NET 应用程序的 Cache 对象中存储的项和 CacheDependency 对象的数组之间的多个依赖项。无法继承此类。”
接下来分析一下这个类的作用,定义一个表态只读的字符串path,他的值来自配置文件,那么先看看这个配置文件里写什么东西 ?打开web.config.找到了那个配置文件为<add key="CacheDependencyAssembly" value="PetShop.TableCacheDependency"/> 他的值为PetShop.TableCacheDependency,类写了一个GetProductDependency()方法,返回值为AggregateCacheDependency的类型,如果这个path不为空,即返回一个DependencyAccess.CreateProductDependency().GetDependency().那么我们也就追踪这个类看看是什么东西?打开DependencyAccess.cs
public static class DependencyAccess {
/// <summary>
/// Method to create an instance of Category dependency implementation
/// </summary>
/// <returns>Category Dependency Implementation</returns>
public static IPetShopCacheDependency CreateCategoryDependency() {
return LoadInstance("Category");
}
/// <summary>
/// Method to create an instance of Product dependency implementation
/// </summary>
/// <returns>Product Dependency Implementation</returns>
public static IPetShopCacheDependency CreateProductDependency() {
return LoadInstance("Product");
}
/// <summary>
/// Method to create an instance of Item dependency implementation
/// </summary>
/// <returns>Item Dependency Implementation</returns>
public static IPetShopCacheDependency CreateItemDependency() {
return LoadInstance("Item");
}
/// <summary>
/// Common method to load dependency class from information provided from configuration file
/// </summary>
/// <param name="className">Type of dependency</param>
/// <returns>Concrete Dependency Implementation instance</returns>
private static IPetShopCacheDependency LoadInstance(string className) {
string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
string fullyQualifiedClass = path + "." + className;
// Using the evidence given in the config file load the appropriate assembly and class
return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
}
}
怎么没有CreateProductDependency()方法里没有GetDependency()这个方法呢?怎么办。继续分析这个DependencyAccess.cs类。CreateProductDependency()代码如下:
public static IPetShopCacheDependency CreateProductDependency() {
return LoadInstance("Product");
}
返回一个类型为IPetShopCacheDependency类型的东西,这个东西就是LoadInstance("Product")这个方法,代码如下:
private static IPetShopCacheDependency LoadInstance(string className) {
string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
string fullyQualifiedClass = path + "." + className;
return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
}
这里用到反射,由上至下我们就可以知道这个是返回一个” PetShop.TableCacheDependency.Product”。
那么我们再将思路跳转到TableCacheDependency项目里的Product.cs
public class Product : TableDependency {
/// <summary>
/// Call its base constructor by passing its specific configuration key
/// </summary>
public Product() : base("ProductTableDependency") { }
}
这个类继承了TahleDependency,调用基类构造函数。那也就要转到基类去看看罗。TableDependency所以的项目文件为TableCacheDependency/ TableDependency.cs,代码如下:
public abstract class TableDependency : PetShop.ICacheDependency.IPetShopCacheDependency {
// This is the separator that's used in web.config
protected char[] configurationSeparator = new char[] { ',' };
protected AggregateCacheDependency dependency = new AggregateCacheDependency();
/// <summary>
/// The constructor retrieves all related configuration and add CacheDependency object accordingly
/// </summary>
/// <param name="configKey">Configuration key for specific derived class implementation</param>
protected TableDependency(string configKey) {
string dbName = ConfigurationManager.AppSettings["CacheDatabaseName"];
string tableConfig = ConfigurationManager.AppSettings[configKey];
string[] tables = tableConfig.Split(configurationSeparator);
foreach (string tableName in tables)
dependency.Add(new SqlCacheDependency(dbName, tableName));
}
public AggregateCacheDependency GetDependency() {
return dependency;
}
}
这个类也是继承了接口PetShop.ICacheDependency.IPetShopCacheDependency,那么,这个TableDependency(string configKey)这个方法有什么用呢。看看源代码:定义字符串dbName,由配置文件里得到这个值为“MSPetShop4”,
这里有个疑问就是定义configurationSeparator怎么是这char类型的数组。这里定义数组有什么作用?怎么就不直接使用char?
这里是将传进来的字符串变成转成AggregateCacheDependency类型的一个集合.使用GetDependency()返回这一类型。那么我们看Product.cs页 public Product() : base("ProductTableDependency") { }
这样我们实例化product之后.使用GetDependency()方法就能获取AggregateCacheDependency类型的值了,这个值就是使用foreach循环用dependency将一个一个值组合起来。而使用base("ProductTableDependency")我们就可以知道放在TableDependency()这里的string 传入为”ProductTableDependency”,那我们直接套进去那值,就可以得到tableConfig的值为"Product,Category"。那么dependencyY就是添加了2个SqlCacheDependency,分别为(“Product”,”MSPetShop4”)及(“Category”,”MSPetShop4”),最终结果只是返回这两个东西合成的一个结果集。
返回后那么缓存依赖this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();我并不知道这里加了个缓存依赖有什么作用?好像这整个页面里没有缓存的设置
- petshop学习笔记(4)
- petshop学习笔记(4) - 缓存
- PetShop学习笔记(一)
- petshop学习笔记(3)
- petshop经典学习笔记
- petshop学习笔记(1)
- petshop学习笔记(2)
- 学习petshop笔记
- PetShop学习笔记----缓存机制
- Petshop 4 学习
- PetShop学习笔记(一)-调试篇
- petshop学习笔记(5)Items.aspx分析
- petshop-jcc学习笔记(一)系统架构
- petshop笔记
- 学习PetShop3.0(4)petshop商品的浏览
- PETSHOP学习
- Petshop 4 学习(李天平整理)
- PETSHOP研究笔记
- marquee 标签的使用
- Eclipse + Glade3 工程配置
- 开机自动运行-----WinCE小技巧&心得
- 冬天来了?
- “将截断字符串或二进制数据。语句已终止。”报错原因?
- petshop学习笔记(4)
- 失望,太失望了北京奥运男子110米栏第1轮 刘翔旧伤复发退赛
- 去掉桌面快捷方式-----WinCE小技巧&心得
- JDK1.5新特性
- JavaScript实现网页的自动滚屏显示
- HttpWebRequest 采集网站数据
- UDP编程实例
- BusinessSkinForm中Calendar组件中文显示BUG的解决
- Tomcat内存设置方法(转)