2009-10-09 51 views
0

我想使用代理模式進行會話處理。刪除會話處理會話代理模式的最佳方法

在我的會話代理類我有類似的東西:

 
public static class SessionProxy 
{ 
    private const string ThemeNameSessionName = "ThemeName"; 
    private const string PasswordExpirationDaysSessionNam = "PasswordExpirationDays"; 

    ///  
    /// Gets or sets theme name.  
    /// 
    public static string ThemeName 
    { 
     get 
     { 
      if (Session[ThemeNameSessionName] == null) 
      { 
       return String.Empty; 
      } 

      return (string)Session[ThemeNameSessionName]; 
     } 

     set 
     { 
      Session[ThemeNameSessionName] = value; 
     } 
    } 

    /// 
    /// Gets or sets how many days to password expiration. 
    ///  
    public static int PasswordExpirationDays 
    { 
     get 
     {    
      return Convert.ToInt32(Session[PasswordExpirationDaysSessionNam]); 
     } 

     set 
     { 
      Session[PasswordExpirationDaysSessionNam] = value; 
     } 
    } 
} 

,所以我用它在我的應用程序爲:

 
SessionProxy.ThemeName = "Default"; 
SessionProxy.PasswordExpirationDays = 5; 

隨着這段代碼我應該使用強類型的會話機制,但..如何刪除會話而不使用字符串文字(如

Session.Remove("ThemeName")
)。 在字符串的情況下,我可以添加到我的屬性:

 
     set 
     { 
if (String.IsNullOrEmpty(value)) 
{ 
    Session.Remove(ThemeNameSessionName); 
} 
else 
{ 
      Session[ThemeNameSessionName] = value; 
} 
     } 

,但在其他類型的情況下(INT,長,日期時間等),我不能使用空(我不想用可空類型)。

你能告訴我這個問題的最佳解決方案嗎? 完美的人會是這樣的,如果可能的:

 
Session.Remove([some magic here]SessionProxy.ThemeName[/magic]); 

還有一件事呢,我需要它在.NET 2.0(雖然soulution用於.NET 3.5也將是很有意思)。

回答

0

首先,我要說的是,你引用的代碼的最後一行:

Session.Remove([some magic here]SessionProxy.ThemeName[/magic]); 

真正應該讀的東西,如:

因爲這是所有關於代理模式,我d認爲即使從Session中移除項而不是直接訪問Session對象(因此否定了代理類的某些有用性),您仍希望通過代理類繼續訪問Session對象!不確定是否abov e只是一個錯字,但我想我會指出來以防萬一。

要回答您的問題,實現此目的的一個相對簡單的方法是將您的代理類中的私有字符串常量替換爲您想要定義的所有會話變量名稱的枚舉。

例如,從上改變你的代碼:

public static class SessionProxy 
{ 
    public enum SessionProxyVars { 
     ThemeName, 
     PasswordExpirationDays 
    } 

    public static string ThemeName { 
     get { 
      if (HttpContext.Current.Session[SessionProxyVars.ThemeName.ToString()] == null) { 
       return String.Empty; 
      } 
      return (string)HttpContext.Current.Session[SessionProxyVars.ThemeName.ToString()]; 
     } 
     set { 
      HttpContext.Current.Session[SessionProxyVars.ThemeName.ToString()] = value; 
     } 
    } 

    public static int PasswordExpirationDays { 
     get { 
      return Convert.ToInt32(HttpContext.Current.Session[SessionProxyVars.PasswordExpirationDays.ToString()]); 
     } 
     set { 
      HttpContext.Current.Session[SessionProxyVars.PasswordExpirationDays.ToString()] = value; 
     } 
    } 

    public static void Remove(SessionProxyVars vartoremove) { 
     HttpContext.Current.Session.Remove(vartoremove.ToString()); 
    } 
} 

請注意,我添加了一個Remove方法,它接受SessionProxyVars參數。

一些簡單的代碼顯示在使用本:

protected void Page_Load(object sender, EventArgs e) 
    { 
     SessionProxy.ThemeName = "MyLovelyTheme"; 
     SessionProxy.PasswordExpirationDays = 3; 
     Response.Write("<br/><br/>"); 
     foreach (string sesskey in HttpContext.Current.Session.Keys) { 
      Response.Write(sesskey + ": " + HttpContext.Current.Session[sesskey].ToString()); 
      Response.Write("<br/>"); 
     } 
     SessionProxy.Remove(SessionProxy.SessionProxyVars.ThemeName); 
     Response.Write("<br/><br/>"); 
     // Enumerate the keys/values of the "real" session to prove it's gone! 
     foreach (string sesskey in HttpContext.Current.Session.Keys) { 
      Response.Write(sesskey + ": " + HttpContext.Current.Session[sesskey].ToString()); 
      Response.Write("<br/>"); 
     }   
    } 

這樣,你繼續只能通過代理類(從而保持封裝),也讓您選擇訪問Session對象刪除特定會話以「強類型」方式變量(即不必求助於字符串文字)。

當然,其中一個缺點是所有的會話變量都必須在枚舉中「預先定義」,但如果您也使用私有字符串常量,那麼情況也是如此。

可能還有另外一種方法來定義一個接口(例如,ISessionVariable<T>允許接口既是通用的(用於強類型的數據類型)也用於「暴露」變量名)並且具有許多類實現這個接口。會話代理類然後可以被重構,以允許「注入」任何實現ISessionVariable<T>接口的類,並且允許getset類型操作以該類型以強類型方式實現類。這允許會話代理類本身完全不知道你將要使用的不同會話變量,但是,這種方法仍然要求所有的類(每個會話變量一個要使用的類)事先定義在應用程序中的某個地方,最終被「注入」Session Proxy類。由於我們只是在談論「包裝」會話對象和一些變量(其中的列表可能是相當固定的並且不是太大),我認爲接口/注入路徑是過量的(雖然可以說設計得更好,當然更多的是DRY) ,並親自,我會去與enum選項。

+0

CraigTP,非常感謝您的解答和例子!它看起來非常適合我。我將爲我當前的項目使用第一種方法(枚舉)。感謝您的設計建議,我將添加到SessionProxy類SessionProxy.Remove,Clear,Abandon和其他我將使用的類。問候! – binball 2009-10-09 09:51:04