Class Scoping Confusion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Grok

    #1

    Class Scoping Confusion

    In writing a class library, one of the classes should only ever be
    instantiated once, and its object should be accessible to every other
    class in the library. How can I do that?

    To provide some actual names for discussion, I'm trying to do this
    with a custom log-writing class, named LogWriter.vb. So I would like
    to declare ..

    Class library project:
    LogWriter.vb
    Drives.vb
    Folders.vb
    Files.vb

    Friend Logger As LogWriter = new LogWriter(LogFi lename)

    and have Drivers, Folders, and Files classes all be able to use the
    sole instantiation "Logger" in their code.

    Hints on how to organize this properly?
  • Phill W.

    #2
    Re: Class Scoping Confusion

    Grok wrote:
    In writing a class library, one of the classes should only ever be
    instantiated once, and its object should be accessible to every other
    class in the library. How can I do that?
    To provide some actual names for discussion, I'm trying to do this
    with a custom log-writing class, named LogWriter.vb. So I would like
    to declare ..
    >
    Class library project:
    LogWriter.vb
    Drives.vb
    Folders.vb
    Files.vb
    >
    Friend Logger As LogWriter = new LogWriter(LogFi lename)
    >
    and have Drivers, Folders, and Files classes all be able to use the
    sole instantiation "Logger" in their code.
    >
    Hints on how to organize this properly?
    Properly? Don't know, but here's how I'd throw it together:

    Public Class LogWriter
    Public ReadOnly Property Drives() as Drives
    Get
    Return New Drives( Me )
    End Get
    End Property
    End Class

    Public Class Drives
    Private Sub New()
    End Sub

    Friend Sub New( ByVal parent as LogWriter )
    m_parent = parent
    End Sub

    Private m_parent as LogWriter = Nothing

    Private ReadOnly Property Parent() as LogWriter
    Get
    return m_parent
    End Get
    End Property

    End Class

    Note the accessors on the Classes and Constructors.

    Anyone "out there" can create an instance of LogWriter - it's
    constructor is Public. They can't, however, create an instance of
    Drives /directly/ - it's constructor is only accessible /inside/ your
    library [assembly].

    To get one, they have to use the Drives property on the LogWriter class,
    which means that your code gets a look in and can deal with linking the
    two objects together.
    Of course, the Drives property doesn't /have/ to be Public...

    HTH,
    Phill W.

    Comment

    • Cor Ligthert[MVP]

      #3
      Re: Class Scoping Confusion

      Grok,

      Normally it is just setting a reference to your library (dll).
      This can using project or by right clicking on the reference tab in your
      solution explorer

      Cor


      "Grok" <grok@valhallal egends.comschre ef in bericht
      news:qepfm3pqdi 9a2u1ichfmnmsih ubsrdvddf@4ax.c om...
      In writing a class library, one of the classes should only ever be
      instantiated once, and its object should be accessible to every other
      class in the library. How can I do that?
      >
      To provide some actual names for discussion, I'm trying to do this
      with a custom log-writing class, named LogWriter.vb. So I would like
      to declare ..
      >
      Class library project:
      LogWriter.vb
      Drives.vb
      Folders.vb
      Files.vb
      >
      Friend Logger As LogWriter = new LogWriter(LogFi lename)
      >
      and have Drivers, Folders, and Files classes all be able to use the
      sole instantiation "Logger" in their code.
      >
      Hints on how to organize this properly?

      Comment

      • =?Utf-8?B?RmFtaWx5IFRyZWUgTWlrZQ==?=

        #4
        RE: Class Scoping Confusion



        "Grok" wrote:
        In writing a class library, one of the classes should only ever be
        instantiated once, and its object should be accessible to every other
        class in the library. How can I do that?
        >
        To provide some actual names for discussion, I'm trying to do this
        with a custom log-writing class, named LogWriter.vb. So I would like
        to declare ..
        >
        Class library project:
        LogWriter.vb
        Drives.vb
        Folders.vb
        Files.vb
        >
        Friend Logger As LogWriter = new LogWriter(LogFi lename)
        >
        and have Drivers, Folders, and Files classes all be able to use the
        sole instantiation "Logger" in their code.
        >
        Hints on how to organize this properly?
        >
        I think your subject through the others off the track. You seem to want to
        create a singleton class. One way that I use is to create a private
        constructor, and public shared instance method. The instance method checks
        to see if a copy exists.

        public class Logger
        private mLogger as Logger = Nothing

        private property Instance as Logger
        get
        if (mLogger is Nothing) then
        mLogger = new Logger()
        endif
        return mLogger
        end get
        end property

        private sub New()
        end sub
        end class

        Comment

        • =?Utf-8?B?RmFtaWx5IFRyZWUgTWlrZQ==?=

          #5
          RE: Class Scoping Confusion

          public class Logger
          private mLogger as Logger = Nothing
          >
          private property Instance as Logger
          get
          if (mLogger is Nothing) then
          mLogger = new Logger()
          endif
          return mLogger
          end get
          end property
          >
          private sub New()
          end sub
          end class
          >
          Sorry, temporary insanity, and typing off the IDE. The Instance property
          should be public, not private...

          Comment

          • =?Utf-8?B?RmFtaWx5IFRyZWUgTWlrZQ==?=

            #6
            Re: Class Scoping Confusion



            "Phill W." wrote:
            Grok wrote:
            >
            In writing a class library, one of the classes should only ever be
            instantiated once, and its object should be accessible to every other
            class in the library. How can I do that?
            >
            To provide some actual names for discussion, I'm trying to do this
            with a custom log-writing class, named LogWriter.vb. So I would like
            to declare ..

            Class library project:
            LogWriter.vb
            Drives.vb
            Folders.vb
            Files.vb

            Friend Logger As LogWriter = new LogWriter(LogFi lename)

            and have Drivers, Folders, and Files classes all be able to use the
            sole instantiation "Logger" in their code.

            Hints on how to organize this properly?
            >
            Properly? Don't know, but here's how I'd throw it together:
            >
            Public Class LogWriter
            Public ReadOnly Property Drives() as Drives
            Get
            Return New Drives( Me )
            End Get
            End Property
            End Class
            >
            Public Class Drives
            Private Sub New()
            End Sub
            >
            Friend Sub New( ByVal parent as LogWriter )
            m_parent = parent
            End Sub
            >
            Private m_parent as LogWriter = Nothing
            >
            Private ReadOnly Property Parent() as LogWriter
            Get
            return m_parent
            End Get
            End Property
            >
            End Class
            >
            Note the accessors on the Classes and Constructors.
            >
            Anyone "out there" can create an instance of LogWriter - it's
            constructor is Public. They can't, however, create an instance of
            Drives /directly/ - it's constructor is only accessible /inside/ your
            library [assembly].
            >
            To get one, they have to use the Drives property on the LogWriter class,
            which means that your code gets a look in and can deal with linking the
            two objects together.
            Of course, the Drives property doesn't /have/ to be Public...
            >
            HTH,
            Phill W.
            >
            Sorry Phill. I missed this when I posted... I didn't copy your paper!

            Comment

            • Grok

              #7
              Re: Class Scoping Confusion

              Thanks for the replies. Yes, I described the question poorly. It is
              solved now. Here is the completed, working solution and test code.

              Family Tree Mike, I was not grasping how to use the Instance property
              as you intended, so was getting two LogWriter objects instead of one.

              All your solution needed was the Shared keyword.

              ===== Implementation =====
              'file: LogWriter.vb
              Imports System.IO
              Namespace GrokQuestion
              'file: LogWriter.vb
              'singleton to write logfile; used by public classes
              Friend Class LogWriter
              Shared mLogWriter As LogWriter = Nothing
              Shared _filename As String
              Friend Sub New()
              End Sub
              Shared ReadOnly Property Instance() As LogWriter
              Get
              Console.WriteLi ne("Get Instance() called.")
              If (mLogWriter Is Nothing) Then
              mLogWriter = New LogWriter()
              End If
              Console.WriteLi ne("Old Filename = """ + _filename +
              """")
              Return mLogWriter
              End Get
              End Property
              Public Property Filename() As String
              Get
              Return _filename
              End Get
              Set(ByVal value As String)
              _filename = value
              End Set
              End Property
              Public Sub WriteLine(ByVal Message As String)
              'open file, write Message, close file
              Console.WriteLi ne(" Message = """ + Message + """")
              Dim sw As System.IO.Strea mWriter = New
              System.IO.Strea mWriter(_filena me)
              sw.WriteLine(Me ssage)
              sw.Close()
              End Sub
              End Class
              End Namespace

              'file: Folders.vb
              Namespace GrokQuestion
              'file: Folders.vb
              Public Class Folders
              Private Logger As LogWriter
              Public Sub New(ByVal LogFilename As String)
              Logger = LogWriter.Insta nce()
              Logger.Filename = LogFilename
              Logger.WriteLin e("Folders class online!")
              End Sub
              End Class
              End Namespace

              'file: Files.vb
              Namespace GrokQuestion
              'file: Files.vb
              Public Class Files
              Private Logger As LogWriter
              Public Sub New(ByVal LogFilename As String)
              Logger = LogWriter.Insta nce()
              Logger.Filename = LogFilename
              Logger.WriteLin e("Files class online!")
              End Sub
              End Class
              End Namespace

              ===== Test =====
              Imports GrokQuestion

              Module Module1

              Sub Main()
              TestFiles()
              TestFolders()
              End Sub

              Private Sub TestFiles()
              Console.WriteLi ne("TestFiles( ) .. expecting old filename =
              """"" + vbCrLf)
              Dim LogFilename As String = "C:\TEMP\First. txt"
              Dim pFiles As GrokQuestion.Gr okQuestion.File s = New
              GrokQuestion.Gr okQuestion.File s(LogFilename)
              Console.WriteLi ne()
              End Sub

              Private Sub TestFolders()
              Console.WriteLi ne("TestFolders () .. expecting old filename =
              ""C:\Test\First .txt""" + vbCrLf)
              Dim LogFilename As String = "C:\TEMP\Second .txt"
              Dim pFolders As GrokQuestion.Gr okQuestion.Fold ers = New
              GrokQuestion.Gr okQuestion.Fold ers(LogFilename )
              Console.WriteLi ne()
              End Sub

              End Module

              ===== Test Output =====
              TestFiles() .. expecting old filename = ""

              Get Instance() called.
              Old Filename = ""
              Message = "Files class online!"

              TestFolders() .. expecting old filename = "C:\Test\First. txt"

              Get Instance() called.
              Old Filename = "C:\TEMP\First. txt"
              Message = "Folders class online!"

              --end

              Comment

              Working...