views:

150

answers:

2

I'm having problems with retrieving multiple instances of a session variable from an InProc session state.

In the following code I persist a simple BusinessObject into a session variable on the Page_Load event. On the click of a button I try to retrieve the object back into 2 new declared instances of the same BusinessObject.

All works great until I change one of the properties in the first instance, it changes the second instance as well.

Is this normal behaviour? I would have thought as these were new instances they wouldn’t demonstrate static behaviour?

Any ideas where I'm going wrong?

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then
            ' create a new instance of a business object and set a containg variable
            Dim BO As New BusinessObject
            BO.SomeVariable = "test"
            ' persist to inproc session
            Session("BO") = BO
        End If

    End Sub

    Protected Sub btnRetrieveSessionVariable_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnRetrieveSessionVariable.Click

        ' retrieve the session variable to a new instance of BusinessObject
        Dim BO1 As New BusinessObject
        If Not Session("BO") Is Nothing Then BO1 = Session("BO")

        ' retrieve the session variable to a new instance of BusinessObject
        Dim BO2 As New BusinessObject
        If Not Session("BO") Is Nothing Then BO2 = Session("BO")

        ' change the property value on the first instance
        BO1.SomeVariable = "test2"

        ' why has this changed on both instances?
        Dim strBO1Property As String = BO1.SomeVariable
        Dim strBO2Property As String = BO2.SomeVariable

    End Sub

    ' simple BusinessObject class
    Public Class BusinessObject
        Private _SomeVariable As String

        Public Property SomeVariable() As String
            Get
                Return _SomeVariable
            End Get
            Set(ByVal value As String)
                _SomeVariable = value
            End Set
        End Property
    End Class
A: 

You're instantiating two new objects, and then setting each of them to be the same object (i.e. the one from session), so your behaviour is exactly as you would expect.

Incidentally, you may wish to consider how your page would perform if a user opens two of these pages in a tab - will your business object in the session then cause you some problems?

Paddy
Thanks Paddy, I had thought about the tabbed issue and have the following in my web.config file. <sessionState mode="InProc" cookieless="UseUri" />This appears to give different session id's in different tabs although you have to do a little bit more work to ensure all hyperlinks work as expected.
sw1sh
A: 

your BO1 and BO2 are the same object BO1 is a name that references some area in memory; BO2 is another name that references the SAME area of memory; Session("BO") references the SAME area of memory.

To truly create different objects BO1 and BO2, you should create a copy of the object - for example implement Clone() method in your business object class.

Axarydax
I suspected that this might be the case but was finding it hard to prove. As my Business Objects are quite deep and require a deep copy I've avoided IClonable and created my own Copy method in the class, as suggested by Brad Adams, http://blogs.msdn.com/brada/archive/2003/04/09/49935.aspx
sw1sh