前幾天看IBuySpy時記在OneNote里面的筆記
2024-07-21 02:15:47
供稿:網友
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;
}
現在到了render方法,這個方法用于輸出控件的html,首先檢查是否啟用緩存,如果沒有,直接調用base.render()直接輸出,然后return。
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);
}
如果啟用了緩存,但是用來保存緩存內容的變量為null,那么就調用base.render()方法,把所有應該輸出的html輸出到_cachedoutput變量中,然后把這個變量的內容放入context.cache中。
output.write(_cachedoutput);
最后,把這個變量中的html內容輸出。