IBuySpy Portal 中使用 PortalModuleControl 这个继承自UserControl的类来作为站点中所有Module的基类,用户控件的工作方式是,当页面上实例化一个用户控件时,自动将它的所有子控件全部Render成HTML,然后输出,为了提高Module的工作效率,每个Module可以设置自己的缓存时间,在缓存时间内,系统不会再重复Render它的所有子控件,而是在第一次Render的时候,把结果HTML文本缓存起来,当下次需要的时候再直接输出。
实现缓存功能,IBuySpy是通过CachedPortalModuleControl实现的。
因为IBuySpy页面上的Module都是通过LoadControl()方法来动态载入到页面上的,像这样:
PortalModuleControl portalModule = (PortalModuleControl) Page.LoadControl(_moduleSettings.DesktopSrc);
portalModule.PortalId = portalSettings.PortalId;
portalModule.ModuleConfiguration = _moduleSettings;
parent.Controls.Add(portalModule);
当检测到一个Module的CacheTime>0时,代码则:
CachedPortalModuleControl portalModule = new CachedPortalModuleControl();
portalModule.PortalId = portalSettings.PortalId;
portalModule.ModuleConfiguration = _moduleSettings;
parent.Controls.Add(portalModule);
就是说,代码不会再载入PortalModuleControl类型的控件了,而是载入CachedPortalModuleControl来实现的。
下面看看CachedPortalModuleControl是如何实现缓存的:
private String _cachedOutput = "";
这里定义了一个String变量,保存缓存的内容
protected override void CreateChildControls() {
if (_moduleConfiguration.CacheTime > 0) {
_cachedOutput = (String) Context.Cache[CacheKey];
}
CreateChildControls()这个方法是在Control类每次被实例化时,都会执行的方法。首先检查这个Module是否启用了缓存,如果启用了,则从Context.Cache中寻找缓存,并载入到_cachedOutput中。
(CachedPortalModuleControl实质上是一个Composite Control,有关复合控件的相关资料,参阅:
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/
cpcondevelopingcompositecontrols.htm)
if (_cachedOutput == null) {
base.CreateChildControls();
PortalModuleControl module = (PortalModuleControl) Page.LoadControl(_moduleConfiguration.DesktopSrc);
module.ModuleConfiguration = this.ModuleConfiguration;
module.PortalId = this.PortalId;
this.Controls.Add(module);
}
如果_cachedOutput为null,那么说明还没有缓存,于是调用base.CreateChildControls(),然后用LoadControl()方法重新(真实的)载入控件,并把这个控件放入本控件的子控件树中。
protected override void Render(HtmlTextWriter output) {
if (_moduleConfiguration.CacheTime == 0) {
base.Render(output);
return;
&n