删除会话代理模式处理的会话的最佳方法

时间:2009-10-09 08:03:35

标签: asp.net session proxy c#-2.0 design-patterns

我想使用代理模式进行会话处理。

在我的会话代理类中,我有类似的东西:

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,long,datetime等)我不能使用null(我不想使用可空类型)。

你能告诉我这个问题的最佳解决方案吗? 如果可能的话,完美的将会是这样的:

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

还有一件事,我在.NET 2.0中需要它(虽然.NET 3.5的解析也很有趣)。

1 个答案:

答案 0 :(得分:0)

首先,我会说你引用的最后一行代码:

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

应该真的读到:

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

由于这完全与代理模式有关,我认为即使从Session中删除项目而不是访问Session,您仍希望通过代理类继续访问Session对象直接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/>"); } } 参数。

一些显示正在使用的简单代码:

ISessionVariable<T>

这样,您只能通过代理类继续访问Session对象(从而保持封装),并且还可以选择以“强类型”方式删除特定的会话变量(即无需求助于字符串文字)。

当然,这样做的一个缺点是你的所有会话变量都必须在你的枚举中“预定义”,但是如果你也使用私有字符串常量那么几乎就是这种情况。

这可能是另一种方法,包括定义一个接口(例如,ISessionVariable<T>允许接口既是通用的(对于强类型数据类型),也是“暴露”变量名称)并且具有类的数量实现此接口。然后可以重构Session Proxy类以允许“注入”实现get接口的任何类,并允许对set实现类的ISessionVariableenum类型操作一种强烈的方式。这允许Session Proxy类本身完全不知道您将使用的不同会话变量,但是,这种方法仍然要求所有类(您将要使用的每个会话变量一个)预先在应用程序的某个地方预先定义,最终“注入”Session Proxy类。由于我们只讨论“包装”会话对象和一些变量(其列表可能相当固定而不是太大),我认为接口/注入路径过度(尽管可以设计得更好,当然更多{{ 3}}),个人而言,我选择{{1}}选项。