2011-10-20 20 views
5

基類頁和用戶控件:如何爲Page和UserControl創建一個基類?

public class MyWebPage : System.Web.UI.Page { } 

public class MyUserControl : System.Web.UI.UserControl { } 

助手,要麼他們可以使用:

void SetSessionValue<T>(string key, T value) { Session[key] = value; } 

如何能夠做到像下面這樣?

public class WebObject // can't inherit from both Page and UserControl { 
    protected void SetSessionValue<T>(string key, T value) { 
     Session[key] = value; 
    } 
} 

public class MyWebPage : WebObject { } 

public class MyUserControl : WebObject { } 

更新:我很興奮第二次希望我能解決這個問題,但唉,它不編譯。

public class WebObject<T> : T 
{ 
} 
public class MyWebPage : WebObject<System.Web.UI.Page> 
{ 
} 
+1

這樣多少方法都會有你,有多少代碼將在每個方法?爲什麼不重複代碼?這一行看起來很簡單,可以擔心這一點。另外,如果'Page'和'UserControl'具有任何公共基類,則可以簡單地在該類型上創建擴展方法。例如。在'System.Web.UI.Control'或者'System.Web.UI.TemplateControl'上 - 你只有在你不需要自定義基類的狀態時才能做到這一點。 –

回答

4

你不能。反正也不容易。我建議僅爲頁面和用戶控件創建一個基類,並在兩者中複製通用代碼。由於用戶控件中包含的頁面,你也可以委託在基礎用戶控件類的基頁類的方法簡單地由Page財產投射到您自己的類型:

// Code in the MyUserControlBase class 
public int SomeCommonMethod() { 
    return ((MyBasePageType)this.Page).SomeCommonMethod(); 
} 

您也可以讓你的生活苦不堪言通過產生由兩個基類實現的接口,並使用DI攔截方法和屬性訪問調用,然後將被路由到某種共同替代類的實際提供的執行情況。我可能不會去那裏:)

+0

我最終創建了一個由基本頁面創建的Context類,並使用在此代碼段中描述的模式在控件庫上放置了一個get屬性訪問器 - 謝謝。 –

1

IIRC Page和UserControl繼承自TemplateControl,因此您可能會從中繼承。

+0

是的,我在看。請注意,Session屬性不在TemplateControl類中。如果是的話,他只需要在TemplateControl中添加一個擴展方法即可。 – AaronLS

1

避免重複的一種方法是有一個助手類,通過靜態屬性實例化並可以從UI中的任何位置訪問(Page,UserControl或UI層中的任何其他類) 。

喜歡的東西:

public class ApplicationContext 
{ 
    // Private constructor to prevent instantiation except through Current property. 
    private ApplicationContext() {} 

    public static ApplicationContext Current 
    { 
     get 
     { 
      ApplicationContext current = 
       HttpContext.Current.Items["AppContext"] as ApplicationContext; 
      if (current = null) 
      { 
       current = new ApplicationContext(); 
       HttpContext.Current.Items["AppContext"] = current; 
      } 
      return current; 
     } 
    } 

    public void SetSessionValue<T>(string key, T value) 
    { 
     HttpContext.Current.Session[key] = value; 
    } 
    ... etc ... 
} 

單一的ApplicationContext實例會住當前請求的生命週期,並且可以使用在任何地方ApplicationContext.Current.SetSessionValue和其他成員共同在你的UI層代碼。

我經常走的更遠不是把通用的方法,如您SetSessionValue在這樣的輔助類,並有可能在那裏特定應用的性能,例如

public class ApplicationContext 
{ 
    ... as above ... 

    public ShoppingBasket ShoppingBasket 
    { 
     ShoppingBasket shoppingBasket = 
      HttpContext.Current.Session["Basket"] as ShoppingBasket; 
     if (shoppingBasket == null) 
     { 
      shoppingBasket = ... e.g. retrieve from database 
      HttpContext.Current.Session["Basket"] = shoppingBasket; 
     } 
     return shoppingBasket; 
    } 
} 

通過這種方式,你可以在任何地方訪問你的UI當前ShoppingBasket實例,而不知道或關心它在會話緩存 - 這是隻知道你的ApplicationContext類的實現細節。

0
  • 1)使具有所有變量的靜態類,你需要
  • 2功能)使自己的用戶控件和Page類,使這些類 打電話給你的靜態函數在Pre_Init和加載覆蓋
  • 3)讓每一個頁面繼承基類。

這是最簡單的方法。

+0

我想不是一個好主意。靜態類是依賴注入的敵人,不允許你爲了簡單的測試而做出模擬。他們也是單身人士,可能無法正常工作。如果你想要一個兩個類都使用的助手類,創建一個普通類,它是接口的實現,並將接口注入到構建這些對象所需的位置。通過這種方式,您可以嘲笑所有您希望進行簡單測試的過程,並且不會因靜態代碼亂丟代碼而導致測試更加困難。 –

相關問題