前幾天看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內容輸出。