删除会话代理模式处理的会话的最佳方法
我想使用代理模式进行会话处理。
在我的会话代理类中,我有类似的东西:
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")). In case of strings I can add to my Properties:
set { if (String.IsNullOrEmpty(value)) { Session.Remove(ThemeNameSessionName); } else { Session[ThemeNameSessionName] = value; } }
但对于其他类型(int、long、datetime 等),我不能使用 null(我不想使用可为 null 的类型)。
你能给我建议这个问题的最佳解决方案吗? 如果可能的话,完美的解决方案将是这样的:
Session.Remove([some magic here]SessionProxy.ThemeName[/magic]);
还有一件事,我在 .NET 2.0 中需要它(尽管 .NET 3.5 的解决方案也很有趣)。
I would like to use Proxy pattern for Session handling.
In my session proxy class I have something like that:
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; } } }
so I use it in my app as:
SessionProxy.ThemeName = "Default"; SessionProxy.PasswordExpirationDays = 5;
With this piece of code I have strongly typed sessions mechanism but.. How to remove session without using string literals (like
Session.Remove("ThemeName")
).
In case of strings I can add to my Properties:
set { if (String.IsNullOrEmpty(value)) { Session.Remove(ThemeNameSessionName); } else { Session[ThemeNameSessionName] = value; } }
but in case of other types (int, long, datetime etc.) I can't use null (I don't want to use nullable types).
Can you advice me the best solution of this problem?
The perfect one will be something like that if possible:
Session.Remove([some magic here]SessionProxy.ThemeName[/magic]);
And one thing yet, I need it in .NET 2.0 (though soulution for .NET 3.5 also will be interesting).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我想说的是,您引用的最后一行代码:
应该真正读成这样:
由于这都是关于代理模式的,我认为您希望继续访问
Session
即使从Session
中删除项目,而不是直接访问Session
对象,也可以通过代理类访问对象(从而否定代理类的一些用处!)不确定是否上面只是一个错字,但我想我会指出以防万一。要回答您的问题,实现此目的的一种相对简单的方法是将代理类中的私有字符串常量替换为您想要定义的所有会话变量名称的枚举。
例如,更改上面的代码:
请注意,我添加了一个采用
SessionProxyVars
参数的Remove
方法。一些简单的代码显示了它的使用情况:
这样,您只能通过代理类继续访问 Session 对象(从而保持封装),并且还可以选择以“强类型”方式删除特定会话变量(即不必求助于字符串文字)。
当然,这样做的一个缺点是所有会话变量都必须在枚举中“预定义”,但如果您也使用私有字符串常量,情况几乎就是这样。
可能还有另一种方法可以实现这一点,涉及定义接口(例如,接口的类,并允许
ISessionVariable
允许接口既通用(对于强类型数据类型)又“公开”变量名称)并让许多类实现这个接口。然后可以重构 Session Proxy 类,以允许“注入”任何实现 ISessionVariableget
和set
以强类型方式对该ISessionVariable
实现类进行类型操作。这允许会话代理类本身完全不知道您将使用的不同会话变量,但是,这种方法仍然要求所有类(您将要使用的每个会话变量一个)是预先准备好的。在应用程序中的某处预先定义,最终“注入”到会话代理类中。由于我们只讨论“包装”会话对象和一些变量(其列表可能相当固定并且不是太大),我认为接口/注入路线是多余的(尽管可以说设计得更好,而且肯定更DRY),就我个人而言,我会选择enum
选项。Firstly, I would say that the last line of code that you quoted:
Should really read something like:
Since this is all about the proxy pattern, I'd think you'd want to continue to access the
Session
object via the proxy class even when removing items from theSession
rather than accessing theSession
object directly (thereby negating some of the usefulness of the proxy class!) Not sure if the above is just a typo, but thought I'd point it out just in case.To answer your question, one relatively simple way of achieving this is to replace your private string constants inside your proxy class with an enumeration of all of the session variable names that you'd like to define.
For example, altering your code from above:
Note that I've added a
Remove
method that takes aSessionProxyVars
parameter.Some simple code showing this in use:
This way, you continue to access the Session object only through the proxy class (thus maintaining encapsulation) and also giving you the option to remove a particular session variable in a "strongly-typed" way (i.e. without having to resort to string literals).
Of course, one downside to this is that all of your session variables must be "pre-defined" within your enumeration, but that was pretty much the case if you're using private string constants, too.
There's probably another way of doing this involving defining an interface (say,
ISessionVariable<T>
allowing the interface to be both generic (for the strongly-typed datatype) as well as "exposing" a variable name) and having a number of classes implement this interface. The Session Proxy class could then be refactored to allow "injection" of any class implementing theISessionVariable<T>
interface, and allowingget
andset
type operation on thatISessionVariable
implementing class in a strongly-typed way. This allows the Session Proxy class itself to be completely agnostic of the different session variables you'll be using, however, this approach does still require that all of the classes (one for each session variable you're going to use) be pre-defined in advance somewhere within your application to ultimately be "injected" into the Session Proxy class. Since we're only talking about "wrapping" the session object and some variables (the list of which is probably fairly fixed and not too large), I think the interface/injection route is overkill (although arguably better designed and certainly more DRY), and personally, I'd go with theenum
option.