2009-10-09 6 views
0

Je souhaite utiliser un modèle de proxy pour la gestion de session.Meilleure méthode pour supprimer la session traitée par le modèle de proxy de session

Dans ma classe proxy de la session j'ai quelque chose comme ça:

 
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; 
     } 
    } 
} 

donc je l'utilise dans mon application comme:

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

Avec ce morceau de code que je suis fortement mécanisme de sessions typé mais .. Comment supprimer la session sans utiliser de littéraux de chaîne (comme

Session.Remove("ThemeName")
). En cas de chaînes que je peux ajouter à mes propriétés:

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

mais dans le cas d'autres types (int, long, datetime etc.) Je ne peux pas utiliser null (Je ne veux pas utiliser des types nullables).

Pouvez-vous me conseiller la meilleure solution de ce problème? Le parfait sera quelque chose comme ça, si possible:

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

Et une chose encore, j'ai besoin dans .NET 2.0 (si Soulution pour .NET 3.5 sera également intéressant).

Répondre

0

Tout d'abord, je dirais que la dernière ligne de code que vous avez cité:

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

Si vraiment lire quelque chose comme:

Depuis cela est sur le modèle de procuration, je Je pense que vous voudrez continuer à accéder à l'objet Session via la classe proxy même lorsque vous supprimez des éléments du Session plutôt que d'accéder directement à l'objet Session (ce qui annule une partie de l'utilité de la classe proxy!). e est juste une faute de frappe, mais je pensais que je le signalerais juste au cas où.

Pour répondre à votre question, un moyen relativement simple d'y parvenir est de remplacer vos constantes de chaînes privées dans votre classe proxy par une énumération de tous les noms de variables de session que vous souhaitez définir.

Par exemple, modifier votre code d'en haut

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()); 
    } 
} 

Notez que j'ai ajouté une méthode Remove qui prend un paramètre SessionProxyVars.

Certains code simple montrant ceci dans l'utilisation:

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/>"); 
     }   
    } 

De cette façon, vous continuez à accéder à l'objet de la session que par la classe proxy (maintenant ainsi l'encapsulation) et en vous donnant la possibilité de supprimer une session particulière variable de manière "fortement typée" (c'est-à-dire sans recourir à des littéraux de chaîne). Bien sûr, un inconvénient à cela est que toutes vos variables de session doivent être "prédéfinies" dans votre énumération, mais c'était à peu près le cas si vous utilisez des chaînes de caractères privées.Il y a probablement une autre façon de faire ceci impliquant la définition d'une interface (par exemple, ISessionVariable<T> permettant à l'interface d'être à la fois générique (pour le type de données fortement typé) et "exposer" un nom de variable) et ayant un certain nombre de classes implémenter cette interface. La classe Session Proxy pourrait alors être refactorisée pour permettre "l'injection" de n'importe quelle classe implémentant l'interface ISessionVariable<T>, et permettant l'opération de type get et set sur cette classe d'implémentation ISessionVariable d'une manière fortement typée. Cela permet à la classe Session Proxy elle-même d'être complètement indépendante des différentes variables de session que vous utiliserez. Cependant, cette approche nécessite toujours que toutes les classes (une pour chaque variable de session que vous allez utiliser) soient pré-programmées. défini à l'avance quelque part dans votre application pour finalement être "injecté" dans la classe Session Proxy. Puisque nous parlons seulement de "wrapper" l'objet de session et certaines variables (dont la liste est probablement assez fixe et pas trop grande), je pense que l'interface/injection est trop grande (bien que sans doute mieux conçue et certainement plus DRY) , et personnellement, j'irais avec l'option enum.

+0

CraigTP, Merci beaucoup pour votre solution et vos exemples !! Cela a l'air parfait pour moi. J'utiliserai la 1ère méthode (enums) pour mon projet actuel. Merci pour vos conseils de conception, je vais ajouter à ma classe SessionProxy SessionProxy.Remove, Clear, Abandon et autres que je vais utiliser. Salutations! – binball

Questions connexes