VB.NET  •  Instantiate a Class That Has No Public Constructors

Listing 1. You can implement a class that has no public constructors and that can be instantiated only through a public shared function. The Create method reads the XML file whose name is passed to it and returns an XmlDataFile object that encapsulates that file's XML Document Object Model (DOM) (in the Document property). However, the Create method maintains all the objects returned so far in a private Hashtable and returns an existing instance if a client asks for a file that was processed already. This technique saves memory and file I/O activity. Also, a client immediately sees changes other clients perform to the XML DOM because they receive a pointer to the same XmlDataFile instance. (A real-world implementation of this class should offer a mechanism for synchronizing read/write operations to the XML DOM from multiple clients.)

Imports System.Xml

Module Module1
   Sub Main()
      ' read an XML file 
      Dim o1 As XmlDataFile = _
         XmlDataFile.Create("c:\settings.xml")
      ' read another XML file
      Dim o2 As XmlDataFile = _
         XmlDataFile.Create("c:\settings2.xml")
      ' read the first file again
      Dim o3 As XmlDataFile = _
         XmlDataFile.Create("c:\settings.xml")

      ' prove that the cached version was used
      Console.WriteLine(o1 Is o3)      ' => true
   End Sub
End Module

' a class that reads and caches XML files

Class XmlDataFile
   ' the name of the associated file 
   Public ReadOnly FileName As String
   ' the XmlDocument that contains the XML data
   Public ReadOnly Document As XmlDocument
   ' the date/time when the file was read
   Public ReadOnly CreateDataTime As DateTime

   ' a private constructor that reads an XML file
   Private Sub New(ByVal filename As String)
      Me.FileName = filename
      Me.Document = New XmlDocument()
      Me.Document.Load(filename)
      Me.CreateDataTime = Now
   End Sub

   ' a private shared hash table that contains
   ' all the objects created so far
   Shared ht As New Hashtable()

   ' a static function working as factory method
   Shared Function Create( _
      ByVal filename As String) As XmlDataFile
      ' check whether this file is associated 
      ' with a previous instance
      If ht.Contains(filename) Then
         ' found, return the existing instance
         Return DirectCast(ht(filename), _
            XmlDataFile)
      Else
         ' not found, create a new instance 
         Dim xdf As New XmlDataFile(filename)
         ' add to the table and return to caller
         ht.Add(filename, xdf)
         Return xdf
      End If
   End Function
End Class