ASP.net:单例类,每个请求只实例化一次?

时间:2011-08-31 17:57:42

标签: asp.net session httpwebrequest singleton instantiation

我有一个名为UserContext的班级,用于跟踪我网站上给定用户的活动。它应该是一个单例类(每个用户只有一个实例)。在Windows窗体应用程序中,我可以编写如下内容:

Class UserContext

    Public Shared Current As New UserContext()

    Private Sub New(appName As String)

    [...]

End Class

但是在ASP.net应用程序上,这将在所有当前用户之间共享。

如果这个类只在一个Page实体中使用,我可以将UserContext实例存储在一个Page变量中 - 它不一定需要在回发中存活。但是其他实体(不了解Page)也调用UserContext,我希望它们都被赋予相同的实例。

我可以做些什么来确保每个 http请求(或每个用户)只对一个类进行一次实例化?我可以使用缓存吗?

Public Shared Function GetContext() As UserContext
    If HttpContext.Current.Cache("CurrentUserContext") Is Nothing Then HttpContext.Current.Cache("CurrentUserContext") = New UserContext()
    Return HttpContext.Current.Cache("CurrentUserContext")
End Function

会话状态可能是更好的选择吗?

缓存和会话状态都能在回发中存活 - 是否有另一个选项可以随每个新请求重置?

感谢您的帮助!

3 个答案:

答案 0 :(得分:5)

HttpContext.Current.Cache将在所有用户之间共享。 HttpContext.Current.Session是每个用户,但会继续存在后续请求。

您需要HttpContext.Current.Items

Public Shared Function GetContext() As UserContext
    If HttpContext.Current.Items("CurrentUserContext") Is Nothing Then HttpContext.Current.Items("CurrentUserContext") = New UserContext()
    Return HttpContext.Current.Items("CurrentUserContext")
End Function

这将确保每个请求和每个用户缓存存储的安全。

答案 1 :(得分:1)

您可以使用HttpContext.Current.Items集合。

答案 2 :(得分:1)

如果要将变量存储的时间超过请求的生命周期,则需要锁定策略来处理并发请求。始终为您的读取分配,并使用双重检查锁定来强制执行单例。

Private ReadOnly lockObj As New Object()
Private Const CurrentUserContextKey As String = "CurrentUserContext"

Public Function GetContext() As UserContext
    Dim session = HttpContext.Current.Session
    Dim userContext = TryCast(session(CurrentUserContextKey), UserContext)
    If userContext Is Nothing Then
        SyncLock lockObj
            userContext = TryCast(session(CurrentUserContextKey), UserContext)
            If userContext Is Nothing Then
                userContext = New UserContext()
                session(CurrentUserContextKey) = userContext
            End If
        End SyncLock
    End If
    Return userContext
End Function