前几天看IBuySpy时记在OneNote里面的笔记

2003-12-12 by 开心就好

[IBuySpy Portal ]{lang="EN-US"}[中使用]{lang="ZH-CN"}[ PortalModuleControl ]{lang="EN-US"}[这个继承自]{lang="ZH-CN"}[UserControl]{lang="EN-US"}[的类来作为站点中所有]{lang="ZH-CN"}[Module]{lang="EN-US"}[的基类,用户控件的工作方式是,当页面上实例化一个用户控件时,自动将它的所有子控件全部]{lang="ZH-CN"}[Render]{lang="EN-US"}[成]{lang="ZH-CN"}[HTML]{lang="EN-US"}[,然后输出,为了提高]{lang="ZH-CN"}[Module]{lang="EN-US"}[的工作效率,每个]{lang="ZH-CN"}[Module]{lang="EN-US"}[可以设置自己的缓存时间,在缓存时间内,系统不会再重复]{lang="ZH-CN"}[Render]{lang="EN-US"}[它的所有子控件,而是在第一次]{lang="ZH-CN"}[Render]{lang="EN-US"}[的时候,把结果]{lang="ZH-CN"}[HTML]{lang="EN-US"}[文本缓存起来,当下次需要的时候再直接输出。]{lang="ZH-CN"}

[实现缓存功能,]{lang="ZH-CN"}[IBuySpy]{lang="EN-US"}[是通过]{lang="ZH-CN"}[CachedPortalModuleControl]{lang="EN-US"}[实现的。]{lang="ZH-CN"}

[因为]{lang="ZH-CN"}[IBuySpy]{lang="EN-US"}[页面上的]{lang="ZH-CN"}[Module]{lang="EN-US"}[都是通过]{lang="ZH-CN"}[LoadControl]{lang="EN-US"}[()]{lang="EN-US"}[方法来动态载入到页面上的,像这样:]{lang="ZH-CN"}

PortalModuleControl portalModule = (PortalModuleControl) Page.LoadControl(_moduleSettings.DesktopSrc);

portalModule.PortalId = portalSettings.PortalId;
portalModule.ModuleConfiguration = _moduleSettings;

parent.Controls.Add(portalModule);

[当检测到一个]{lang="ZH-CN"}[Module]{lang="EN-US"}[的]{lang="ZH-CN"}[CacheTime>0]{lang="EN-US"}[时,代码则:]{lang="ZH-CN"}

CachedPortalModuleControl portalModule = new CachedPortalModuleControl();

portalModule.PortalId = portalSettings.PortalId;
portalModule.ModuleConfiguration = _moduleSettings;

parent.Controls.Add(portalModule);

[就是说,代码不会再载入]{lang="ZH-CN"}[PortalModuleControl]{lang="EN-US"}[类型的控件了,而是载入]{lang="ZH-CN"}[CachedPortalModuleControl]{lang="EN-US"}[来实现的。]{lang="ZH-CN"}

[下面看看]{lang="ZH-CN"}[CachedPortalModuleControl]{lang="EN-US"}[是如何实现缓存的:]{lang="ZH-CN"}

[private Strin]{lang="ZH-CN"}[g ]{lang="EN-US"}[_cach]{lang="ZH-CN"}[e]{lang="EN-US"}[dOutput = "";]{lang="ZH-CN"}

[这里定义了一个]{lang="ZH-CN"}[String]{lang="EN-US"}[变量,保存缓存的内容]{lang="ZH-CN"}

protected override void CreateChildControls() {

if (_moduleConfiguration.CacheTime > 0) {

_cachedOutput = (String) Context.Cache[CacheKey];

}

[CreateChildControls()这个方法是在]{lang="ZH-CN"}[Control]{lang="EN-US"}[类每次被实例化时,都会执行的方法。首先检查这个]{lang="ZH-CN"}[Module]{lang="EN-US"}[是否启用了缓存,如果启用了,则从]{lang="ZH-CN"}[Context.Cache]{lang="EN-US"}[中寻找缓存,并载入到]{lang="ZH-CN"}[_cachedOutput]{lang="EN-US"}[中。]{lang="ZH-CN"}

[(]{lang="ZH-CN"}[CachedPortalModuleControl]{lang="EN-US"}[实质上是一个]{lang="ZH-CN"}[Composite Control]{lang="EN-US"}[,有关复合控件的相关资料,参阅:]{lang="ZH-CN"}

[ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/
cpcondevelopingcompositecontrols.htm)]{lang="ZH-CN"}

if (_cachedOutput == null) {

base.CreateChildControls();

PortalModuleControl module = (PortalModuleControl) Page.LoadControl(_moduleConfiguration.DesktopSrc);

module.ModuleConfiguration = this.ModuleConfiguration;

module.PortalId = this.PortalId;

this.Controls.Add(module);

}

[如果]{lang="ZH-CN"}[_cachedOutput]{lang="EN-US"}[为]{lang="ZH-CN"}[null]{lang="EN-US"}[,那么说明还没有缓存,于是调用]{lang="ZH-CN"}[base.CreateChildControls()]{lang="EN-US"}[,然后用]{lang="ZH-CN"}[LoadControl]{lang="EN-US"}[()]{lang="EN-US"}[方法重新(真实的)载入控件,并把这个控件放入本控件的子控件树中。]{lang="ZH-CN"}

protected override void Render(HtmlTextWriter output) {

if (_moduleConfiguration.CacheTime == 0) {

base.Render(output);

return;

}

[现在到了]{lang="ZH-CN"}[Render]{lang="EN-US"}[方法,这个方法用于输出控件的]{lang="ZH-CN"}[HTML]{lang="EN-US"}[,首先检查是否启用缓存,如果没有,直接调用]{lang="ZH-CN"}[base.Render()]{lang="EN-US"}[直接输出,然后]{lang="ZH-CN"}[return]{lang="EN-US"}[。]{lang="ZH-CN"}

if (_cachedOutput == null) {

TextWriter tempWriter = new StringWriter();

base.Render(new HtmlTextWriter(tempWriter));

_cachedOutput = tempWriter.ToString();

Context.Cache.Insert(CacheKey, _cachedOutput, null, DateTime.Now.AddSeconds(_moduleConfiguration.CacheTime), TimeSpan.Zero);

}

[如果启用了缓存,但是用来保存缓存内容的变量为]{lang="ZH-CN"}[null]{lang="EN-US"}[,那么就调用]{lang="ZH-CN"}[base.Render()]{lang="EN-US"}[方法,把所有应该输出的]{lang="ZH-CN"}[HTML]{lang="EN-US"}[输出到]{lang="ZH-CN"}[_cachedOutput]{lang="EN-US"}[变量中,然后把这个变量的内容放入]{lang="ZH-CN"}[Context]{lang="EN-US"}[.Cache]{lang="EN-US"}[中。]{lang="ZH-CN"}

output.Write(_cachedOutput);

[最后,把这个变量中的]{lang="ZH-CN"}[HTML]{lang="EN-US"}[内容输出。]{lang="ZH-CN"}


Comments