Sharing an instance of an object across classes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?QmV0aA==?=

    Sharing an instance of an object across classes

    Hello.

    I'm trying to find another way to share an instance of an object with other
    classes.

    I started by passing the instance to the other class's constructor, like this:

    Friend Class clsData
    Private m_objSQLClient As clsSQLClient
    Private m_objUsers As clsUsers
    Private m_sConnect As String

    Friend Sub connect(ByVal bDebuggerAttach ed As Boolean)
    Dim sServer As String
    Dim sDB As String

    If bDebuggerAttach ed Then
    sServer = "test"
    Else
    sServer = "prod"
    End If
    sDB = "appdb"

    m_sConnect = "Data Source=" & sServer & ";Database= " & sDB & ";Integrate d
    Security=true"
    m_sConnect = m_sConnect & ";Applicati on Name = " &
    My.Application. Info.AssemblyNa me

    m_objSQLClient = New clsSQLClient
    m_objSQLClient. connect(m_sConn ect)

    m_objUsers = New clsUsers(m_objS QLClient)
    End Sub
    End Class

    Friend Class clsUsers
    Private m_objSQLClient As clsSQLClient
    Private m_dtUser As DataTable

    Friend Sub New(ByVal objSQLClient As clsSQLClient)
    m_objSQLClient = objSQLClient
    End Sub

    Friend Function markEntry() As String
    Try
    m_dtUser = m_objSQLClient. tableForEdit("u sers")

    This works, but I don't like it. I want clsUsers to refer directly to the
    instance variable in clsData instead of passing a parameter.

    Then I saw an example using inheritance that I liked, so I added:

    Protected Friend Function sqlClient() As clsSQLClient
    Return m_objSQLClient
    End Function

    To clsData and I deleted the constructor in clsUsers and changed the code to:

    Friend Class clsUsers
    Inherits clsData
    Private m_dtUser As DataTable

    Friend Function markEntry() As String
    Try
    m_dtUser = MyBase.sqlClien t.tableForEdit( "users")

    but it doesn't work- it raises an exception when clsUsers.markEn try
    references mybase.sqlClien t.

    Is there another way I can do this, or do I need to stick with passing the
    object instance as a parameter?

    Thanks for any help,

    -Beth
  • Tom Shelton

    #2
    Re: Sharing an instance of an object across classes

    On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
    Hello.
    >
    I'm trying to find another way to share an instance of an object with other
    classes.
    >
    I started by passing the instance to the other class's constructor, like this:
    >
    Friend Class clsData
    Private m_objSQLClient As clsSQLClient
    Private m_objUsers As clsUsers
    Private m_sConnect As String
    >
    Friend Sub connect(ByVal bDebuggerAttach ed As Boolean)
    Dim sServer As String
    Dim sDB As String
    >
    If bDebuggerAttach ed Then
    sServer = "test"
    Else
    sServer = "prod"
    End If
    sDB = "appdb"
    >
    m_sConnect = "Data Source=" & sServer & ";Database= " & sDB & ";Integrate d
    Security=true"
    m_sConnect = m_sConnect & ";Applicati on Name = " &
    My.Application. Info.AssemblyNa me
    >
    m_objSQLClient = New clsSQLClient
    m_objSQLClient. connect(m_sConn ect)
    >
    m_objUsers = New clsUsers(m_objS QLClient)
    End Sub
    End Class
    >
    Friend Class clsUsers
    Private m_objSQLClient As clsSQLClient
    Private m_dtUser As DataTable
    >
    Friend Sub New(ByVal objSQLClient As clsSQLClient)
    m_objSQLClient = objSQLClient
    End Sub
    >
    Friend Function markEntry() As String
    Try
    m_dtUser = m_objSQLClient. tableForEdit("u sers")
    >
    This works, but I don't like it. I want clsUsers to refer directly to the
    instance variable in clsData instead of passing a parameter.
    >
    Then I saw an example using inheritance that I liked, so I added:
    >
    Protected Friend Function sqlClient() As clsSQLClient
    Return m_objSQLClient
    End Function
    >
    To clsData and I deleted the constructor in clsUsers and changed the code to:
    >
    Friend Class clsUsers
    Inherits clsData
    Private m_dtUser As DataTable
    >
    Friend Function markEntry() As String
    Try
    m_dtUser = MyBase.sqlClien t.tableForEdit( "users")
    >
    but it doesn't work- it raises an exception when clsUsers.markEn try
    references mybase.sqlClien t.
    >
    Is there another way I can do this, or do I need to stick with passing the
    object instance as a parameter?
    >
    Thanks for any help,
    >
    -Beth
    First of all, it is usually a bad idea to allow other classes, included sub
    classes direct access to instance variables. It should always be through
    properties. In fact, I try to never access field data even inside my own
    class without going through properties :) The main reason is that properties
    provide a layer of abstraction, that allows the implmentation change without
    having affecting client code... For instance, what if a field needs to
    become a calculated value? If you went through the property, all is well, but
    if you allowed client code to directly access the field then you are in
    trouble. Believe me, I have learned this lesson the hard way :)

    That said... Let's see if we can't come up with a good answer, to your
    problem :) Based off of what I'm seeing here, I don't see the problem with
    your first example? Why do you feel it is better not to pass the parameter to
    the constructor - though, I would probably do it more like this:


    Class clsData
    Private _sqlClient As clsSqlClient
    private _users As clsUsers

    Public Sub New (....)
    SqlClient = new clsSqlClient(.. ..)

    Users = New clsUsers (SqlClient)
    End Sub

    Private Property Users As clsUsers
    Get
    Return _users
    End Get
    Set (ByVal Value As clsUsers)
    _users = Value
    End Set
    End Property
    Private Property SqlClient As clsSqlClient
    Get
    Return _sqlClient
    End Get
    Set (ByVal Value As SqlClient)
    _sqlClient = Value
    End Set
    End Property

    End Class


    Anyway, that's my oppinion, others may differ. And it maybe another approach
    my be better if you application has a different achitecture. Like, do all
    isntances of all classes use the same SqlClient instance, etc.


    --
    Tom Shelton

    Comment

    • =?Utf-8?B?QmV0aA==?=

      #3
      Re: Sharing an instance of an object across classes

      Hi, Tom.
      Thanks for your response.

      Yes, multiple classes share a single instance of clsSQLClient connected to
      the server. Right now, I'm passing it as a parameter to each of the class's
      constructors.

      ClsData is intended to wrap all of the data access functions of the
      application.
      ClsSQLClient Imports System.Data.Sql Client, and is the only class to do so.
      ClsUsers has a 'has-a' relationship with clsData: the data object includes a
      representation of the users table in the database.

      I'm trying to figure out how to share an instance of a variable without
      using inheritance. For a 'has-a' relationship (composition,) I've read
      you're supposed to use interfaces instead of inheritance, but interfaces
      don't contain implementation, so you can't share instances of objects at
      runtime.

      Maybe what I'm doing is what I'm 'supposed' to be doing, but I don't like my
      class diagram having all these other classes point to my clsSQLClient.
      I only want clsData to point to it, and all the other classes to point to
      clsData.

      When I tried to use inheritance, I got a nicer diagram, but broke the app.

      Also, I'm not sure what you're referring to when you say it's:
      a bad idea to allow other classes, included sub classes direct access to
      instance variables

      I didn't think I was allowing direct access to the private instance
      variables outside of the classes. I agree, it's a bad idea, but I'm not
      seeing where I'm doing it.

      Thanks again for your response. I'm sticking with the parameters for now.

      -Beth

      "Tom Shelton" wrote:
      On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
      Hello.

      I'm trying to find another way to share an instance of an object with other
      classes.

      I started by passing the instance to the other class's constructor, like this:

      Friend Class clsData
      Private m_objSQLClient As clsSQLClient
      Private m_objUsers As clsUsers
      Private m_sConnect As String

      Friend Sub connect(ByVal bDebuggerAttach ed As Boolean)
      Dim sServer As String
      Dim sDB As String

      If bDebuggerAttach ed Then
      sServer = "test"
      Else
      sServer = "prod"
      End If
      sDB = "appdb"

      m_sConnect = "Data Source=" & sServer & ";Database= " & sDB & ";Integrate d
      Security=true"
      m_sConnect = m_sConnect & ";Applicati on Name = " &
      My.Application. Info.AssemblyNa me

      m_objSQLClient = New clsSQLClient
      m_objSQLClient. connect(m_sConn ect)

      m_objUsers = New clsUsers(m_objS QLClient)
      End Sub
      End Class

      Friend Class clsUsers
      Private m_objSQLClient As clsSQLClient
      Private m_dtUser As DataTable

      Friend Sub New(ByVal objSQLClient As clsSQLClient)
      m_objSQLClient = objSQLClient
      End Sub

      Friend Function markEntry() As String
      Try
      m_dtUser = m_objSQLClient. tableForEdit("u sers")

      This works, but I don't like it. I want clsUsers to refer directly to the
      instance variable in clsData instead of passing a parameter.

      Then I saw an example using inheritance that I liked, so I added:

      Protected Friend Function sqlClient() As clsSQLClient
      Return m_objSQLClient
      End Function

      To clsData and I deleted the constructor in clsUsers and changed the code to:

      Friend Class clsUsers
      Inherits clsData
      Private m_dtUser As DataTable

      Friend Function markEntry() As String
      Try
      m_dtUser = MyBase.sqlClien t.tableForEdit( "users")

      but it doesn't work- it raises an exception when clsUsers.markEn try
      references mybase.sqlClien t.

      Is there another way I can do this, or do I need to stick with passing the
      object instance as a parameter?

      Thanks for any help,

      -Beth
      >
      First of all, it is usually a bad idea to allow other classes, included sub
      classes direct access to instance variables. It should always be through
      properties. In fact, I try to never access field data even inside my own
      class without going through properties :) The main reason is that properties
      provide a layer of abstraction, that allows the implmentation change without
      having affecting client code... For instance, what if a field needs to
      become a calculated value? If you went through the property, all is well, but
      if you allowed client code to directly access the field then you are in
      trouble. Believe me, I have learned this lesson the hard way :)
      >
      That said... Let's see if we can't come up with a good answer, to your
      problem :) Based off of what I'm seeing here, I don't see the problem with
      your first example? Why do you feel it is better not to pass the parameter to
      the constructor - though, I would probably do it more like this:
      >
      >
      Class clsData
      Private _sqlClient As clsSqlClient
      private _users As clsUsers
      >
      Public Sub New (....)
      SqlClient = new clsSqlClient(.. ..)
      >
      Users = New clsUsers (SqlClient)
      End Sub
      >
      Private Property Users As clsUsers
      Get
      Return _users
      End Get
      Set (ByVal Value As clsUsers)
      _users = Value
      End Set
      End Property
      Private Property SqlClient As clsSqlClient
      Get
      Return _sqlClient
      End Get
      Set (ByVal Value As SqlClient)
      _sqlClient = Value
      End Set
      End Property
      >
      End Class
      >
      >
      Anyway, that's my oppinion, others may differ. And it maybe another approach
      my be better if you application has a different achitecture. Like, do all
      isntances of all classes use the same SqlClient instance, etc.
      >
      >
      --
      Tom Shelton
      >

      Comment

      • sloan

        #4
        Re: Sharing an instance of an object across classes


        I think that whole bit of code is ... .. hurting.....

        You're tied your clsUsers to always coming from the database.
        Based on the notation (hungarian), this looks like leftover VB6 code, and no
        one at your workplace has taken a VB.NET course yet.

        Take a look here:

        http://sholliday.space s.live.com/Blog/cns!A68482B9628 A842A!140.entry

        This is a layered application.

        The business objects and collections are seperate from the code that creates
        them.
        The code that creates them can use database related calls, OR (better) the
        business objects and collections can be created totally independant of a
        database.
        (One reason? UnitTesting)

        Your connection strings should be kept in a config file. You've got
        hardcoding all over the place.


        I'm not trying to be mean...but youch....... I have no idea what that code
        is doing. I might have in 1999.



        ............... .



        "Beth" <Beth@discussio ns.microsoft.co mwrote in message
        news:8D42B0F4-6D5C-4A5F-B32A-330F97A7B8C0@mi crosoft.com...
        Hello.
        >
        I'm trying to find another way to share an instance of an object with
        other
        classes.
        >
        I started by passing the instance to the other class's constructor, like
        this:
        >
        Friend Class clsData
        Private m_objSQLClient As clsSQLClient
        Private m_objUsers As clsUsers
        Private m_sConnect As String
        >
        Friend Sub connect(ByVal bDebuggerAttach ed As Boolean)
        Dim sServer As String
        Dim sDB As String
        >
        If bDebuggerAttach ed Then
        sServer = "test"
        Else
        sServer = "prod"
        End If
        sDB = "appdb"
        >
        m_sConnect = "Data Source=" & sServer & ";Database= " & sDB & ";Integrate d
        Security=true"
        m_sConnect = m_sConnect & ";Applicati on Name = " &
        My.Application. Info.AssemblyNa me
        >
        m_objSQLClient = New clsSQLClient
        m_objSQLClient. connect(m_sConn ect)
        >
        m_objUsers = New clsUsers(m_objS QLClient)
        End Sub
        End Class
        >
        Friend Class clsUsers
        Private m_objSQLClient As clsSQLClient
        Private m_dtUser As DataTable
        >
        Friend Sub New(ByVal objSQLClient As clsSQLClient)
        m_objSQLClient = objSQLClient
        End Sub
        >
        Friend Function markEntry() As String
        Try
        m_dtUser = m_objSQLClient. tableForEdit("u sers")
        >
        This works, but I don't like it. I want clsUsers to refer directly to the
        instance variable in clsData instead of passing a parameter.
        >
        Then I saw an example using inheritance that I liked, so I added:
        >
        Protected Friend Function sqlClient() As clsSQLClient
        Return m_objSQLClient
        End Function
        >
        To clsData and I deleted the constructor in clsUsers and changed the code
        to:
        >
        Friend Class clsUsers
        Inherits clsData
        Private m_dtUser As DataTable
        >
        Friend Function markEntry() As String
        Try
        m_dtUser = MyBase.sqlClien t.tableForEdit( "users")
        >
        but it doesn't work- it raises an exception when clsUsers.markEn try
        references mybase.sqlClien t.
        >
        Is there another way I can do this, or do I need to stick with passing the
        object instance as a parameter?
        >
        Thanks for any help,
        >
        -Beth

        Comment

        • Tom Shelton

          #5
          Re: Sharing an instance of an object across classes

          On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
          Hi, Tom.
          Thanks for your response.
          >
          Yes, multiple classes share a single instance of clsSQLClient connected to
          the server. Right now, I'm passing it as a parameter to each of the class's
          constructors.
          >
          ClsData is intended to wrap all of the data access functions of the
          application.
          ClsSQLClient Imports System.Data.Sql Client, and is the only class to do so.
          ClsUsers has a 'has-a' relationship with clsData: the data object includes a
          representation of the users table in the database.
          >
          Hmmm... Sounds to me like you need something along the lines of a
          singleton...

          Class clsData
          Private Shared _instance As New clsData
          ....

          ' your public instance methods here

          Public Shared ReadOnly Property Instance As clsData
          Get
          return _instance
          End Get
          End Property
          End Class

          Class User
          ...

          Public Sub SomeSub()
          clsData.Instanc e.DoCoolStuff()
          End Sub
          End Class


          <snip>
          Also, I'm not sure what you're referring to when you say it's:
          a bad idea to allow other classes, included sub classes direct access to
          instance variables
          >
          I didn't think I was allowing direct access to the private instance
          variables outside of the classes. I agree, it's a bad idea, but I'm not
          seeing where I'm doing it.
          >
          Your probably not :) I didn't look that close, but I was just commenting on
          your remark about allowing clsUsers direct access to the instance variable.
          Thanks again for your response. I'm sticking with the parameters for now.
          >
          -Beth
          >
          --
          Tom Shelton

          Comment

          • Tom Shelton

            #6
            Re: Sharing an instance of an object across classes

            On 2008-10-29, sloan <sloan@ipass.ne twrote:
            >
            I think that whole bit of code is ... .. hurting.....
            >
            You're tied your clsUsers to always coming from the database.
            Based on the notation (hungarian), this looks like leftover VB6 code, and no
            one at your workplace has taken a VB.NET course yet.
            >
            Take a look here:
            >
            http://sholliday.space s.live.com/Blog/cns!A68482B9628 A842A!140.entry
            >
            This is a layered application.
            >
            The business objects and collections are seperate from the code that creates
            them.
            The code that creates them can use database related calls, OR (better) the
            business objects and collections can be created totally independant of a
            database.
            (One reason? UnitTesting)
            >
            Your connection strings should be kept in a config file. You've got
            hardcoding all over the place.
            >
            >
            I'm not trying to be mean...but youch....... I have no idea what that code
            is doing. I might have in 1999.
            >
            >
            >
            ...............
            >
            >
            >
            Yep... I have to agree.

            --
            Tom Shelton

            Comment

            • =?Utf-8?B?QmV0aA==?=

              #7
              Re: Sharing an instance of an object across classes

              Thanks, Tom.

              It looks recursive, but I see where the new instance of the class is created
              during the declaration instead of outside the class, enforcing the single
              shared instance, as long as no caller decides to instantiate the class.

              I got the instance reference to work without passing an instance of the
              class as a parameter to other class's constructors, and that was what I
              wanted.

              I think what I was looking for before was some kind of 'functional'
              inheritance, which doesn't seem to exist.

              I was thinking when you instantiate a derived class, it 'latched on' to the
              base class instance in memory, so you could call the base class's functions
              at runtime and get the same results as if you'd called the base class's
              functions directly, but it doesn't work that way. The derived class has its
              own instance of myBase separate from any other instance, which makes sense,
              because you're not guaranteed to have any instance of the base class in
              memory or you could have several instances, and then which one would the
              derived class 'latch on' to?

              Thanks again for your response. I'd seen the 'shared' keyword before, but
              not used on a new instance of itself.

              I guess that's what they mean by 'singleton.'

              -Beth

              "Tom Shelton" wrote:
              On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
              Hi, Tom.
              Thanks for your response.

              Yes, multiple classes share a single instance of clsSQLClient connected to
              the server. Right now, I'm passing it as a parameter to each of the class's
              constructors.

              ClsData is intended to wrap all of the data access functions of the
              application.
              ClsSQLClient Imports System.Data.Sql Client, and is the only class to do so.
              ClsUsers has a 'has-a' relationship with clsData: the data object includes a
              representation of the users table in the database.
              >
              Hmmm... Sounds to me like you need something along the lines of a
              singleton...
              >
              Class clsData
              Private Shared _instance As New clsData
              ....
              >
              ' your public instance methods here
              >
              Public Shared ReadOnly Property Instance As clsData
              Get
              return _instance
              End Get
              End Property
              End Class
              >
              Class User
              ...
              >
              Public Sub SomeSub()
              clsData.Instanc e.DoCoolStuff()
              End Sub
              End Class
              >
              >
              <snip>
              >
              Also, I'm not sure what you're referring to when you say it's:
              a bad idea to allow other classes, included sub classes direct access to
              instance variables

              I didn't think I was allowing direct access to the private instance
              variables outside of the classes. I agree, it's a bad idea, but I'm not
              seeing where I'm doing it.
              >
              Your probably not :) I didn't look that close, but I was just commenting on
              your remark about allowing clsUsers direct access to the instance variable.
              >
              Thanks again for your response. I'm sticking with the parameters for now.

              -Beth
              >
              --
              Tom Shelton
              >

              Comment

              • =?Utf-8?B?QmV0aA==?=

                #8
                Re: Sharing an instance of an object across classes

                but you can't listen for events from a singleton...

                "Beth" wrote:
                Thanks, Tom.
                >
                It looks recursive, but I see where the new instance of the class is created
                during the declaration instead of outside the class, enforcing the single
                shared instance, as long as no caller decides to instantiate the class.
                >
                I got the instance reference to work without passing an instance of the
                class as a parameter to other class's constructors, and that was what I
                wanted.
                >
                I think what I was looking for before was some kind of 'functional'
                inheritance, which doesn't seem to exist.
                >
                I was thinking when you instantiate a derived class, it 'latched on' to the
                base class instance in memory, so you could call the base class's functions
                at runtime and get the same results as if you'd called the base class's
                functions directly, but it doesn't work that way. The derived class has its
                own instance of myBase separate from any other instance, which makes sense,
                because you're not guaranteed to have any instance of the base class in
                memory or you could have several instances, and then which one would the
                derived class 'latch on' to?
                >
                Thanks again for your response. I'd seen the 'shared' keyword before, but
                not used on a new instance of itself.
                >
                I guess that's what they mean by 'singleton.'
                >
                -Beth
                >
                "Tom Shelton" wrote:
                >
                On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
                Hi, Tom.
                Thanks for your response.
                >
                Yes, multiple classes share a single instance of clsSQLClient connected to
                the server. Right now, I'm passing it as a parameter to each of the class's
                constructors.
                >
                ClsData is intended to wrap all of the data access functions of the
                application.
                ClsSQLClient Imports System.Data.Sql Client, and is the only class to do so.
                ClsUsers has a 'has-a' relationship with clsData: the data object includes a
                representation of the users table in the database.
                >
                Hmmm... Sounds to me like you need something along the lines of a
                singleton...

                Class clsData
                Private Shared _instance As New clsData
                ....

                ' your public instance methods here

                Public Shared ReadOnly Property Instance As clsData
                Get
                return _instance
                End Get
                End Property
                End Class

                Class User
                ...

                Public Sub SomeSub()
                clsData.Instanc e.DoCoolStuff()
                End Sub
                End Class


                <snip>
                Also, I'm not sure what you're referring to when you say it's:
                a bad idea to allow other classes, included sub classes direct access to
                instance variables
                >
                I didn't think I was allowing direct access to the private instance
                variables outside of the classes. I agree, it's a bad idea, but I'm not
                seeing where I'm doing it.
                >
                Your probably not :) I didn't look that close, but I was just commenting on
                your remark about allowing clsUsers direct access to the instance variable.
                Thanks again for your response. I'm sticking with the parameters for now.
                >
                -Beth
                >
                --
                Tom Shelton

                Comment

                • Tom Shelton

                  #9
                  Re: Sharing an instance of an object across classes

                  On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
                  Thanks, Tom.
                  >
                  It looks recursive, but I see where the new instance of the class is created
                  during the declaration instead of outside the class, enforcing the single
                  shared instance, as long as no caller decides to instantiate the class.
                  >
                  I got the instance reference to work without passing an instance of the
                  class as a parameter to other class's constructors, and that was what I
                  wanted.
                  >
                  I think what I was looking for before was some kind of 'functional'
                  inheritance, which doesn't seem to exist.
                  >
                  I was thinking when you instantiate a derived class, it 'latched on' to the
                  base class instance in memory, so you could call the base class's functions
                  at runtime and get the same results as if you'd called the base class's
                  functions directly, but it doesn't work that way. The derived class has its
                  own instance of myBase separate from any other instance, which makes sense,
                  because you're not guaranteed to have any instance of the base class in
                  memory or you could have several instances, and then which one would the
                  derived class 'latch on' to?
                  >
                  Thanks again for your response. I'd seen the 'shared' keyword before, but
                  not used on a new instance of itself.
                  >
                  I guess that's what they mean by 'singleton.'
                  >
                  -Beth
                  Actually, there is a mistake in that implementation. .. clsData should have a
                  private constructor. In other words, it should prevent any other classes from
                  instantiating it :)

                  Here is the correction...

                  Class clsData
                  Private Shared _instance As New clsData
                  ....
                  Private Sub New ()
                  ' this should probably read your connection
                  ' information from the connectionstrin gs section
                  ' of your config file
                  End Sub

                  ' your public instance methods here

                  Public Shared ReadOnly Property Instance As clsData
                  Get
                  return _instance
                  End Get
                  End Property
                  End Class

                  Now, there is only on instance of this class. I am not saying this is the
                  correct architecture. The more I've read, it sounds like you are trying to
                  develop a n-teir type application. You might want to do some reading on that
                  topic.

                  --
                  Tom Shelton

                  Comment

                  • =?Utf-8?B?QmV0aA==?=

                    #10
                    Re: Sharing an instance of an object across classes

                    Thanks again, Tom.
                    I like that better.

                    I've read about n-tier development, but that's not really what I'm doing.
                    Everything is in one assembly for one project with one database. It's not a
                    large-scale thing, just departmental. It's not dependent on any modules
                    running on other servers, in other words.

                    "Tom Shelton" wrote:
                    On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
                    Thanks, Tom.

                    It looks recursive, but I see where the new instance of the class is created
                    during the declaration instead of outside the class, enforcing the single
                    shared instance, as long as no caller decides to instantiate the class.

                    I got the instance reference to work without passing an instance of the
                    class as a parameter to other class's constructors, and that was what I
                    wanted.

                    I think what I was looking for before was some kind of 'functional'
                    inheritance, which doesn't seem to exist.

                    I was thinking when you instantiate a derived class, it 'latched on' to the
                    base class instance in memory, so you could call the base class's functions
                    at runtime and get the same results as if you'd called the base class's
                    functions directly, but it doesn't work that way. The derived class has its
                    own instance of myBase separate from any other instance, which makes sense,
                    because you're not guaranteed to have any instance of the base class in
                    memory or you could have several instances, and then which one would the
                    derived class 'latch on' to?

                    Thanks again for your response. I'd seen the 'shared' keyword before, but
                    not used on a new instance of itself.

                    I guess that's what they mean by 'singleton.'

                    -Beth
                    >
                    Actually, there is a mistake in that implementation. .. clsData should have a
                    private constructor. In other words, it should prevent any other classes from
                    instantiating it :)
                    >
                    Here is the correction...
                    >
                    Class clsData
                    Private Shared _instance As New clsData
                    ....
                    Private Sub New ()
                    ' this should probably read your connection
                    ' information from the connectionstrin gs section
                    ' of your config file
                    End Sub
                    >
                    ' your public instance methods here
                    >
                    Public Shared ReadOnly Property Instance As clsData
                    Get
                    return _instance
                    End Get
                    End Property
                    End Class
                    >
                    Now, there is only on instance of this class. I am not saying this is the
                    correct architecture. The more I've read, it sounds like you are trying to
                    develop a n-teir type application. You might want to do some reading on that
                    topic.
                    >
                    --
                    Tom Shelton
                    >

                    Comment

                    • Tom Shelton

                      #11
                      Re: Sharing an instance of an object across classes

                      On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
                      but you can't listen for events from a singleton...
                      >
                      Sure you can.

                      I'm still not convined that this is the right path. I think really, more
                      information is needed on what your trying to achieve.

                      If I understand, now that I've read more - it sounds like your trying to
                      create a data abstraction layer. There are many ways to accomplish this, so
                      you might want to do a little more reading on n-tier achitectures. There are
                      in fact whole applications that will generate this kind of stuff for you :)

                      But, for simple stuff, I tend to do stuff like this

                      Friend MustInherit Class DataAccess
                      Private _connectionStri ng As String

                      Public Sub New(ByVal connectionStrin g As String)
                      _connectionStri ng = connectionStrin g
                      End Sub

                      ' generic data access stuff

                      Public Function GetList(Of T) (ByVal procedure) As List(Of T)
                      Dim l As New List(Of T)
                      ' I use attributes and reflection to generate the objects here
                      ' from the resulting recordset. basically, i map the properties
                      ' of type T to specific fields in the record set.
                      Return l
                      End Function
                      End Class

                      Friend Class UserDataAccess
                      Inherits DataAccess

                      Public Sub New (ByVal connectionStrin g As String)
                      MyBase.New(conn ectionString)
                      End Sub

                      Public Function GetUsers() As List(Of User)
                      Return GetList(Of User)("getallus ers")
                      End Function

                      Public Class

                      Public Class UserBuisnessLog ic
                      Private _dataAccess As UserDataAccess

                      Public Sub New (string connectionStrin g)
                      _dataAccess = new UserDataAccess
                      End Sub

                      Public Function GetUsers() As List(Of User)
                      return _dataAccess.Get Users()
                      End Function
                      End Class

                      This of course Really, Really, basic. I have a framework that I've been
                      evolving overtime :) And to be real honest, it's all in C# - but many of the
                      concepts apply to VB. But, you might want to take a look at some resources on
                      this topic.

                      --
                      Tom Shelton

                      Comment

                      • Tom Shelton

                        #12
                        Re: Sharing an instance of an object across classes

                        On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
                        Thanks again, Tom.
                        I like that better.
                        >
                        I've read about n-tier development, but that's not really what I'm doing.
                        Everything is in one assembly for one project with one database. It's not a
                        large-scale thing, just departmental. It's not dependent on any modules
                        running on other servers, in other words.
                        >
                        N-Tier is more about a separation of layers then it is about multiple servers,
                        etc. N-tier is about layering of you application into multiple independent
                        layers. I often have one dll that contains all three layers - the point is
                        that I can easily separate them out, split them up or replace layers with
                        different pieces should the need arise.

                        --
                        Tom Shelton

                        Comment

                        • =?Utf-8?B?QmV0aA==?=

                          #13
                          Re: Sharing an instance of an object across classes

                          Thanks, sloan.
                          I think.

                          Yes, I've been developing over 10 years now. I started with VB3, believe it
                          or not.
                          And yes, I have taken a couple of .NET courses. Didn't get through to me, I
                          guess.

                          Actually, I used to think I could support anybody else's VB code, until I
                          saw some written by a guy experienced in COBOL. Then I saw some code written
                          by engineers. Then I saw some code written by a FoxPro developer.

                          I usually rewrite the old stuff instead of trying to figure out what they
                          were doing.

                          So I gather...
                          You don't like my naming convention. Personally, I like being able to tell
                          the data type from the variable name.

                          You were thinking I was working on components that didn't access the
                          database directly? That I was implementing some middle-tier components? I'm
                          doing the whole thing, soup to nuts (actually, I've done the whole thing and
                          I'm revisiting it.)
                          I could have introduced additional layers of abstraction, but for this
                          project, it didn't make sense. It would be introducing abstraction for
                          abstraction's sake, not reuse.

                          You want to see connection strings in a config file instead of code. I'm
                          not a huge fan of config files, but I have seen them promoted. It's an
                          internal application using integrated security, so all I'm concerned about is
                          keeping people from accessing the wrong back end. I need to keep people in
                          prod from connecting to test, even though prod started out in the test
                          environment and they're structurally the same. I'm even exposing the
                          connection in Help/About so we're all clear on where we're connecting at
                          runtime.

                          You want to see the use of lists instead of collections. I think I can
                          accommodate you, there.

                          It's certainly not my intention to write code which pains you young
                          whipper-snappers, so if there's more I was supposed to pick up on, feel free
                          to share.

                          I need to take my nap now.

                          -Beth

                          "sloan" wrote:
                          >
                          I think that whole bit of code is ... .. hurting.....
                          >
                          You're tied your clsUsers to always coming from the database.
                          Based on the notation (hungarian), this looks like leftover VB6 code, and no
                          one at your workplace has taken a VB.NET course yet.
                          >
                          Take a look here:
                          >
                          http://sholliday.space s.live.com/Blog/cns!A68482B9628 A842A!140.entry
                          >
                          This is a layered application.
                          >
                          The business objects and collections are seperate from the code that creates
                          them.
                          The code that creates them can use database related calls, OR (better) the
                          business objects and collections can be created totally independant of a
                          database.
                          (One reason? UnitTesting)
                          >
                          Your connection strings should be kept in a config file. You've got
                          hardcoding all over the place.
                          >
                          >
                          I'm not trying to be mean...but youch....... I have no idea what that code
                          is doing. I might have in 1999.
                          >
                          >
                          >
                          ............... .
                          >
                          >
                          >
                          "Beth" <Beth@discussio ns.microsoft.co mwrote in message
                          news:8D42B0F4-6D5C-4A5F-B32A-330F97A7B8C0@mi crosoft.com...
                          Hello.

                          I'm trying to find another way to share an instance of an object with
                          other
                          classes.

                          I started by passing the instance to the other class's constructor, like
                          this:

                          Friend Class clsData
                          Private m_objSQLClient As clsSQLClient
                          Private m_objUsers As clsUsers
                          Private m_sConnect As String

                          Friend Sub connect(ByVal bDebuggerAttach ed As Boolean)
                          Dim sServer As String
                          Dim sDB As String

                          If bDebuggerAttach ed Then
                          sServer = "test"
                          Else
                          sServer = "prod"
                          End If
                          sDB = "appdb"

                          m_sConnect = "Data Source=" & sServer & ";Database= " & sDB & ";Integrate d
                          Security=true"
                          m_sConnect = m_sConnect & ";Applicati on Name = " &
                          My.Application. Info.AssemblyNa me

                          m_objSQLClient = New clsSQLClient
                          m_objSQLClient. connect(m_sConn ect)

                          m_objUsers = New clsUsers(m_objS QLClient)
                          End Sub
                          End Class

                          Friend Class clsUsers
                          Private m_objSQLClient As clsSQLClient
                          Private m_dtUser As DataTable

                          Friend Sub New(ByVal objSQLClient As clsSQLClient)
                          m_objSQLClient = objSQLClient
                          End Sub

                          Friend Function markEntry() As String
                          Try
                          m_dtUser = m_objSQLClient. tableForEdit("u sers")

                          This works, but I don't like it. I want clsUsers to refer directly to the
                          instance variable in clsData instead of passing a parameter.

                          Then I saw an example using inheritance that I liked, so I added:

                          Protected Friend Function sqlClient() As clsSQLClient
                          Return m_objSQLClient
                          End Function

                          To clsData and I deleted the constructor in clsUsers and changed the code
                          to:

                          Friend Class clsUsers
                          Inherits clsData
                          Private m_dtUser As DataTable

                          Friend Function markEntry() As String
                          Try
                          m_dtUser = MyBase.sqlClien t.tableForEdit( "users")

                          but it doesn't work- it raises an exception when clsUsers.markEn try
                          references mybase.sqlClien t.

                          Is there another way I can do this, or do I need to stick with passing the
                          object instance as a parameter?

                          Thanks for any help,

                          -Beth
                          >
                          >
                          >

                          Comment

                          • sloan

                            #14
                            Re: Sharing an instance of an object across classes

                            You can write layers into one assembly....lay ers are a logical seperation.

                            I think its easier to put layers in different assembies (to avoid crossing
                            incorrect boundaries).... ..but you can do layers in one assembly.

                            I think of Tiers as different boundaries.

                            But you should be doing Layered development.





                            "Beth" <Beth@discussio ns.microsoft.co mwrote in message
                            news:24BFBFBC-2994-417E-9D57-26E9061275CA@mi crosoft.com...
                            Thanks again, Tom.
                            I like that better.
                            >
                            I've read about n-tier development, but that's not really what I'm doing.
                            Everything is in one assembly for one project with one database. It's not
                            a
                            large-scale thing, just departmental. It's not dependent on any modules
                            running on other servers, in other words.
                            >
                            "Tom Shelton" wrote:
                            >
                            >On 2008-10-29, Beth <Beth@discussio ns.microsoft.co mwrote:
                            Thanks, Tom.
                            >
                            It looks recursive, but I see where the new instance of the class is
                            created
                            during the declaration instead of outside the class, enforcing the
                            single
                            shared instance, as long as no caller decides to instantiate the class.
                            >
                            I got the instance reference to work without passing an instance of the
                            class as a parameter to other class's constructors, and that was what I
                            wanted.
                            >
                            I think what I was looking for before was some kind of 'functional'
                            inheritance, which doesn't seem to exist.
                            >
                            I was thinking when you instantiate a derived class, it 'latched on' to
                            the
                            base class instance in memory, so you could call the base class's
                            functions
                            at runtime and get the same results as if you'd called the base class's
                            functions directly, but it doesn't work that way. The derived class
                            has its
                            own instance of myBase separate from any other instance, which makes
                            sense,
                            because you're not guaranteed to have any instance of the base class in
                            memory or you could have several instances, and then which one would
                            the
                            derived class 'latch on' to?
                            >
                            Thanks again for your response. I'd seen the 'shared' keyword before,
                            but
                            not used on a new instance of itself.
                            >
                            I guess that's what they mean by 'singleton.'
                            >
                            -Beth
                            >>
                            >Actually, there is a mistake in that implementation. .. clsData should
                            >have a
                            >private constructor. In other words, it should prevent any other classes
                            >from
                            >instantiatin g it :)
                            >>
                            >Here is the correction...
                            >>
                            >Class clsData
                            > Private Shared _instance As New clsData
                            > ....
                            >Private Sub New ()
                            >' this should probably read your connection
                            >' information from the connectionstrin gs section
                            >' of your config file
                            >End Sub
                            >>
                            > ' your public instance methods here
                            >>
                            > Public Shared ReadOnly Property Instance As clsData
                            > Get
                            > return _instance
                            > End Get
                            > End Property
                            >End Class
                            >>
                            >Now, there is only on instance of this class. I am not saying this is
                            >the
                            >correct architecture. The more I've read, it sounds like you are trying
                            >to
                            >develop a n-teir type application. You might want to do some reading on
                            >that
                            >topic.
                            >>
                            >--
                            >Tom Shelton
                            >>

                            Comment

                            • sloan

                              #15
                              Re: Sharing an instance of an object across classes


                              //which pains you young
                              whipper-snappers,//
                              Huh?
                              I've been developing code for 10 years also (as in being paid ... for a
                              living).
                              I started with VB4, 16Bit for Win3.1.

                              So I don't think age has anything to do with it.


                              If you count the space invader knock-off game I wrote in the 6th grade on a
                              TRS80 using ascii characters, then I've been writing code for 24 years on
                              and off.
                              Wait, I took a Apple 2e course during my 5th grade summer. Make that 25
                              years.





                              "Beth" <Beth@discussio ns.microsoft.co mwrote in message
                              news:513683F2-1DEE-4565-9C4A-8642B4CD024F@mi crosoft.com...
                              Thanks, sloan.
                              I think.
                              >
                              Yes, I've been developing over 10 years now. I started with VB3, believe
                              it
                              or not.
                              And yes, I have taken a couple of .NET courses. Didn't get through to me,
                              I
                              guess.
                              >
                              Actually, I used to think I could support anybody else's VB code, until I
                              saw some written by a guy experienced in COBOL. Then I saw some code
                              written
                              by engineers. Then I saw some code written by a FoxPro developer.
                              >
                              I usually rewrite the old stuff instead of trying to figure out what they
                              were doing.
                              >
                              So I gather...
                              You don't like my naming convention. Personally, I like being able to
                              tell
                              the data type from the variable name.
                              >
                              You were thinking I was working on components that didn't access the
                              database directly? That I was implementing some middle-tier components?
                              I'm
                              doing the whole thing, soup to nuts (actually, I've done the whole thing
                              and
                              I'm revisiting it.)
                              I could have introduced additional layers of abstraction, but for this
                              project, it didn't make sense. It would be introducing abstraction for
                              abstraction's sake, not reuse.
                              >
                              You want to see connection strings in a config file instead of code. I'm
                              not a huge fan of config files, but I have seen them promoted. It's an
                              internal application using integrated security, so all I'm concerned about
                              is
                              keeping people from accessing the wrong back end. I need to keep people
                              in
                              prod from connecting to test, even though prod started out in the test
                              environment and they're structurally the same. I'm even exposing the
                              connection in Help/About so we're all clear on where we're connecting at
                              runtime.
                              >
                              You want to see the use of lists instead of collections. I think I can
                              accommodate you, there.
                              >
                              It's certainly not my intention to write code which pains you young
                              whipper-snappers, so if there's more I was supposed to pick up on, feel
                              free
                              to share.
                              >
                              I need to take my nap now.
                              >
                              -Beth
                              >
                              "sloan" wrote:
                              >
                              >>
                              >I think that whole bit of code is ... .. hurting.....
                              >>
                              >You're tied your clsUsers to always coming from the database.
                              >Based on the notation (hungarian), this looks like leftover VB6 code, and
                              >no
                              >one at your workplace has taken a VB.NET course yet.
                              >>
                              >Take a look here:
                              >>
                              >http://sholliday.space s.live.com/Blog/cns!A68482B9628 A842A!140.entry
                              >>
                              >This is a layered application.
                              >>
                              >The business objects and collections are seperate from the code that
                              >creates
                              >them.
                              >The code that creates them can use database related calls, OR (better)
                              >the
                              >business objects and collections can be created totally independant of a
                              >database.
                              >(One reason? UnitTesting)
                              >>
                              >Your connection strings should be kept in a config file. You've got
                              >hardcoding all over the place.
                              >>
                              >>
                              >I'm not trying to be mean...but youch....... I have no idea what that
                              >code
                              >is doing. I might have in 1999.
                              >>
                              >>
                              >>
                              >.............. ..
                              >>
                              >>
                              >>
                              >"Beth" <Beth@discussio ns.microsoft.co mwrote in message
                              >news:8D42B0F 4-6D5C-4A5F-B32A-330F97A7B8C0@mi crosoft.com...
                              Hello.
                              >
                              I'm trying to find another way to share an instance of an object with
                              other
                              classes.
                              >
                              I started by passing the instance to the other class's constructor,
                              like
                              this:
                              >
                              Friend Class clsData
                              Private m_objSQLClient As clsSQLClient
                              Private m_objUsers As clsUsers
                              Private m_sConnect As String
                              >
                              Friend Sub connect(ByVal bDebuggerAttach ed As Boolean)
                              Dim sServer As String
                              Dim sDB As String
                              >
                              If bDebuggerAttach ed Then
                              sServer = "test"
                              Else
                              sServer = "prod"
                              End If
                              sDB = "appdb"
                              >
                              m_sConnect = "Data Source=" & sServer & ";Database= " & sDB &
                              ";Integrate d
                              Security=true"
                              m_sConnect = m_sConnect & ";Applicati on Name = " &
                              My.Application. Info.AssemblyNa me
                              >
                              m_objSQLClient = New clsSQLClient
                              m_objSQLClient. connect(m_sConn ect)
                              >
                              m_objUsers = New clsUsers(m_objS QLClient)
                              End Sub
                              End Class
                              >
                              Friend Class clsUsers
                              Private m_objSQLClient As clsSQLClient
                              Private m_dtUser As DataTable
                              >
                              Friend Sub New(ByVal objSQLClient As clsSQLClient)
                              m_objSQLClient = objSQLClient
                              End Sub
                              >
                              Friend Function markEntry() As String
                              Try
                              m_dtUser = m_objSQLClient. tableForEdit("u sers")
                              >
                              This works, but I don't like it. I want clsUsers to refer directly to
                              the
                              instance variable in clsData instead of passing a parameter.
                              >
                              Then I saw an example using inheritance that I liked, so I added:
                              >
                              Protected Friend Function sqlClient() As clsSQLClient
                              Return m_objSQLClient
                              End Function
                              >
                              To clsData and I deleted the constructor in clsUsers and changed the
                              code
                              to:
                              >
                              Friend Class clsUsers
                              Inherits clsData
                              Private m_dtUser As DataTable
                              >
                              Friend Function markEntry() As String
                              Try
                              m_dtUser = MyBase.sqlClien t.tableForEdit( "users")
                              >
                              but it doesn't work- it raises an exception when clsUsers.markEn try
                              references mybase.sqlClien t.
                              >
                              Is there another way I can do this, or do I need to stick with passing
                              the
                              object instance as a parameter?
                              >
                              Thanks for any help,
                              >
                              -Beth
                              >>
                              >>
                              >>

                              Comment

                              Working...