开发者

ASP.net: singleton class, instantiate just once per request?

I have a class called UserContext that tracks the activities of a given user on my website. It should be a singleton class (just one instance per user). In a Windows Forms application, I'd could write something like this:

Class UserContext

    Public Shared Current As New UserContext()

    Private Sub New(appName As String)

    [...]

End Class

But on an ASP.net app, this would get shared across all current users.

If this class were only being used within a Page entity I could just store the UserContext instance in a Page variable—it doesn't necessarily need to survive postbacks. But other entities (that don't know about Page) also call UserContext, and I'd like them all to be given the same instance.

What can I do to ensure that a class is only instantiated once per http request (or per user)? Could I use the cache for this?

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

Might session state be a better option?

Cache and session state both survive postbacks—is there another option that resets with each new request?

开发者_Python百科

Thanks for your help!


HttpContext.Current.Cache will be shared among all users. HttpContext.Current.Session is per user but persists for subsequent requests.

You need 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

This will ensure a safe per request and per user cache store.


You can use the HttpContext.Current.Items collection.


You will need a locking strategy to handle concurrent requests if you are storing the variable for longer than the life of the request. Always assign on your read, and employ double-checked locking to enforce singleton.

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜