首先,我想说的是你引用的最后一行代码:
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());
}
}
请注意,我添加了一个采用SessionProxyVars 参数的Remove 方法。
一些简单的代码展示了它的使用:
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> 接口的类,并允许以强类型的方式对该ISessionVariable 实现类进行get 和set 类型操作。这允许会话代理类本身完全不知道您将使用的不同会话变量,但是,这种方法仍然需要所有类(您将要使用的每个会话变量一个)都是预先的预先在应用程序中的某个地方定义,最终被“注入”到 Session Proxy 类中。由于我们只是在谈论“包装”会话对象和一些变量(这些变量的列表可能相当固定且不太大),我认为接口/注入路线是多余的(尽管可以说设计得更好,当然更多@987654321 @),就个人而言,我会选择 enum 选项。