views:

1325

answers:

2

I have had several occasions recently to access a specific class several times over a relatively small time frame.

So I've been storing the value of the class in Session and trying to access it on page load, if it's not available creating a new instance and storing that in session.

So instead of constantly replicating the same code for different classes on different pages I'm trying to create an extension method to do this for me.

I want to use it like this

Dim objName as MyClass

objName.SessionSinglton()

So far this is what I have for my extension method:

    <Extension()> _
    Public Sub SessionSinglton(ByRef ClassObject As Object)
        Dim objType As Type = ClassObject.GetType
        Dim sessionName As String = objType.FullName
        If TypeOf HttpContext.Current.Session(sessionName) Is objType And HttpContext.Current.Session(sessionName) <> "" Then
            ClassObject = HttpContext.Current.Session(sessionName)
        Else
            Dim singlton As Object = New objType???????

            HttpContext.Current.Session(sessionName) = singlton
            ClassObject = singlton

        End If
    End Sub

I'm stuck on what to do when I make my new instance of my class (it would have to have a New() sub)

I'm not sure where to go from here... or even if this is the best way to do it. Thanks in advance for any help.

+1  A: 

I figured it out and am posting my code for reference. While digging thru pages about Class/Object Factories (thanks RBarry) I found several references to Activator.CreateInstance() in the System.Reflection Class I came up with this.

Imports Microsoft.VisualBasic
Imports System.Runtime.CompilerServices
Imports System.Reflection

Public Module enviornmentUtilities
    <Extension()> _
    Public Function SessionSinglton(ByVal objType As Type) As Object
        Dim sessionName As String = objType.FullName.ToString
        If Not HttpContext.Current.Session(sessionName) Is Nothing Then
            HttpContext.Current.Trace.Write(HttpContext.Current.Session(sessionName).ToString)
            Return HttpContext.Current.Session(sessionName)
        Else
            Dim ss = Activator.CreateInstance(objType)
            HttpContext.Current.Session(sessionName) = ss
            Return ss
        End If
    End Function
End Module

This will let you create a session based singleton from any class that does not require parameters in the new method (which isn't required for this to work)

To test I made a simple Class:

  Public Class HasNew
        Public FreshInstance As Boolean = True
        Public Sub New()
            HttpContext.Current.Trace.Warn("This Class has a new method")
        End Sub
        Public Sub CheckFreshness()
            If FreshInstance Then
                HttpContext.Current.Trace.Warn("Fresh HasNew Instance")
                FreshInstance = False
            Else
                HttpContext.Current.Trace.Warn("NotFresh HasNew Instance")
            End If
        End Sub
        Public Shared Function type() As Type
            Return GetType(HasNew)
        End Function
        Public Shared Function SessionSinglton() As HasNew
            Return GetType(HasNew).SessionSinglton
        End Function
    End Class

You'll notice the two Public Shared Methods type() and SessionSinglton which calls the above extension method.

With those two functions added we have three ways to initiate the Session Singlton demonstrated here:

Dim HN As HasNew

HN = HasNew.SessionSinglton
HN.CheckFreshness()

HN = HasNew.type.SessionSinglton
HN.CheckFreshness()

HN = GetType(HasNew).SessionSinglton
HN.CheckFreshness()

The Trace Output for this file is as follows:

This Class has a new method
Fresh HasNew Instance
NotFresh HasNew Instance
NotFresh HasNew Instance

The classes new() method is accessed on the first call to the SessionSinglton method and subsequent calls reflect that the instance is in fact being pulled from memory.

I hope this helps someone else in the future.

Birk
+1 Very nice solution. I'll be keeping this.
RBarryYoung
+1  A: 

If you used generics you could just do New T(). Also your SessionSingleton returns "object" type, requiring casting. I did not test this but it should work.

Imports Microsoft.VisualBasic
Imports System.Runtime.CompilerServices
Imports System.Reflection

Public Module enviornmentUtilities
    <Extension()> _
    Public Function SessionSinglton(Of T As {Class, New})(ByVal obj As T) As T
        Dim sessionName As String = obj.GetType.Name
        If Not HttpContext.Current.Session(sessionName) Is Nothing Then
            HttpContext.Current.Trace.Write(HttpContext.Current.Session(sessionName).ToString)
            Return HttpContext.Current.Session(sessionName)
        Else
            Dim ss = New T()
            HttpContext.Current.Session(sessionName) = ss
            Return ss
        End If
    End Function
End Module
epitka
This is interesting, I'll need to do some more research on using generics. I can't figure out how to use this extension... using my example class I tried: Dim HN As HasNewHN = HasNew.SessionSinglton2(): Reference to a non-shared member requires an object reference. AlsoDim HN As HasNewHN = HN.SessionSinglton2(): Object reference not set to an instance of an object.
Birk
Well, yes, extension methods require instance of the type they are extending, so what you are trying to do will not work.
epitka