as described in the next section。 ■Note For the examples in this chapter; use the XML shown in the listings。 XML is not difficult to learn; but for now; you’ll get by with what I show you here。 For more information about XML; visit the MSDN XML Developer Center at http://msdn2。microsoft。/en…us/xml/default。aspx。 Reading a Configuration File Reading a configuration file is very simple because the Framework es with an easy to…use configuration API。 For example; to read the value for the key Assemblies; use the following code; which would be added to your application when the application first starts; such as in the Main() method of a console program。 Dim value As String = _ System。Configuration。ConfigurationManager。AppSettings(〃Assemblies〃) …………………………………………………………Page 344…………………………………………………………… 322 CH AP T E R 1 2 ■ L E A R N I N G A B OU T A PP L I CA TI O N CO N F I G U R AT IO N AN D D Y N A M I C L O AD I N G ConfigurationManager is a shared class that provides the entry point to reading items from a configuration file。 In this example; a couple assumptions have been made。 The first assumption is that you want to read the configuration settings from the application that is currently executing。 The second assumption is that you want to read the configuration items stored within the XML node 。 Based on those two assumptions; the settings are stored in a shared prop erty named AppSettings; which returns an instance of type NameValueCollection。 (The way that AppSettings is referenced makes it appear as if AppSettings were an indexer; which it is not。) When retrieving the buffer of ma…separated identifiers using ConfigurationManager; you need to parse the buffer and then make sense of the information; as described in the next section。 Dynamically Loading an Assembly In terms; to use the configuration file with a dynamically loaded application; you need to load the assembly; and from the assembly; instantiate the type。 You can reference assemblies locally and also reference them from the GAC。 Dynamically Instantiating a Type The code to dynamically instantiate a type requires parsing the ma…separated buffer into its respective identifiers。 To keep things organized; the three pieces of information are stored in a class。 This can be called a data class because it has only data members。 The data class is a placeholder; needed only by the code used to dynamically load the type。 This makes it possible to define the data class as a private class; because a private class implies only the parent class can instantiate it。 With the ConfigurationLoader class defined as the class used to dynamically instantiate other types; the private class is declared as follows (added to the Definitions project): Public Class ConfigurationLoader Private _availableTypes As Dictionary(Of String; ConfigurationInfo) = _ New Dictionary(Of String; ConfigurationInfo) Private Class ConfigurationInfo Public AssemblyName As String Public EasyName As String Public TypeName As String End Class End Class ConfigurationInfo contains three data members: AssemblyName; EasyName; and TypeName。 The class is prefixed with Private; indicating that nothing external to the ConfigurationLoader class can see the configuration。 Had ConfigurationInfo been declared with the Public keyword; the following code would have been legal。 Dim cls As ConfigurationLoader。ConfigurationInfo = _ New ConfigurationLoader。ConfigurationInfo() …………………………………………………………Page 345…………………………………………………………… CH AP T E R 1 2 ■ L E AR N IN G AB O U T AP P L I CAT I ON CO N F IG U R AT IO N A N D D Y N A M IC L O AD IN G 323 ConfigurationInfo is used to store the information from the configuration file。 The config uration information is cross…referenced using a Dictionary; where the key is the EasyName data member。 To parse the configuration information and create the individual instances of ConfigurationInfo; the following code (part of ConfigurationLoader) is used。 Imports System。Configuration Public Sub Load() Dim value As String = ConfigurationManager。AppSettings(〃assemblies〃) Dim values As String() = value。Split(〃;〃c) Dim c1 As Integer = 0 Do While (c1 《 values。Length) Dim configInfo As New ConfigurationInfo() configInfo。EasyName = values(c1) configInfo。TypeName = values((c1 + 1)) configInfo。AssemblyName = values((c1 + 2)) _availableTypes。Add(values(c1); configInfo) c1 = (c1 + 3) Loop End Sub The configuration is read using AppSettings; and then split into an array of string element values。 Processing three array elements at a time iterates the array。 With every iteration; an instance of ConfigurationInfo is created。 Once the buffer has been processed; it is possible to dynamically instantiate a type using the following ConfigurationLoader method。 Imports System。Reflection 。 。 。 Public Function Instantiate(Of RequestedType)(ByVal identifier As String) _ As RequestedType If Not _availableTypes。ContainsKey(identifier) Then Throw New ArgumentException((〃identifier (〃 & identifier & _ 〃) is not a listed type〃)) End If Dim info As ConfigurationInfo = _availableTypes。Item