按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
cannot instantiate an instance of the type。
The following is the singleton code for ConfigurationLoader (placed in the Definitions
assembly)。
Public Class ConfigurationLoader
Public Shared ReadOnly Property Instance() As ConfigurationLoader
Get
Return ConfigurationLoader。_instance
End Get
End Property
Private Sub New()
_availableTypes = New Dictionary(Of String; ConfigurationInfo)()
End Sub
Private Shared _instance As ConfigurationLoader
Shared Sub New()
_instance = New ConfigurationLoader()
End Sub
。 。 。
The singleton property Instance is declared as Shared; allowing a reference of
ConfigurationLoader。Instance。 The implementation of the shared property must reference a
shared data member; which is the data member _instance in this example。 The data member
_instance is instantiated by the shared constructor Shared New()。 The instance constructor will
instantiate the Dictionary _availableTypes。
■Note The shared constructor is called before the instance constructor and therefore before any client code
has a chance to access members of the class。
Using the Instantiated Type
Now that we’ve covered the singleton aspect; we need to get back to the original problem of
writing the code to instantiate a type dynamically。 The following code is used to instantiate
Impl1 in the Main() method of CallRuntimeImplementation’s principal module。
…………………………………………………………Page 348……………………………………………………………
326 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
ConfigurationLoader。Instance。Load()
Dim definition as IDefinition = _
ConfigurationLoader。Instance。Instantiate(Of IDefinition)(〃Impl1〃)
Console。WriteLine(definition。TranslateWord(〃hello〃))
■Note You might get errors running the code。 If you do; it is because the assemblies are not in the same
path and the dynamic loading methods cannot find the assemblies。 Solve this by copying all of the assemblies
into a single directory and running the code。
The first line is used to retrieve the assembly and type information from the configuration
file。 The second line is used to instantiate Impl1 and then cast Implementations1。
Implementation to type IDefinition。 The cast will work because the IDefinition interface has
been implemented by Implementations1。Implementation。 The assigned variable definition will
reference a valid object instance that implements IDefinition and the method TranslateWord()。
At this point; we need to step back and reflect on what has occurred。 We have defined
within a configuration file the location of a type。 Some source code in the application read the
configuration file at runtime and stored the available types。 The calling code knew about only
the abstract type made available under the label Impl1 and knew it implemented the interface
IDefinition。 Then; using some magic involving dynamic techniques; the type’s assembly
is loaded and instantiated。 This process is unique because an administrator has the ability to
update where and what type should be instantiated and called; without needing to repile
or update the infrastructure。 That flexibility makes it much simpler for you to update function
ality without having to update the caller of the functionality。
■Note The ability to dynamically update the functionality is of benefit to the administrator of the application。
There is minimal benefit to the developer; because the developer has already converted the architecture to
use ponents。 In general; developers consider this approach to ponents as building a plug…in architecture。
Enhancing the Configuration File
The configuration file is a bit of a clumsy definition because all of the available types are
stored in a single key/value pair。 It would be preferable to be able to define custom items in
the configuration file; as follows:
This approach is preferable because it is easier to read and understand; thus reducing the
chances that you will have an error。 Additionally; because the various identifiers are broken up;
you don’t need to build a lengthy single…line string。
…………………………………………………………Page 349……………………………………………………………
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 327
■Note For simplicity; we will have only a single dynamic type; represented by the XML element。
In a plete solution; you would use the same approach with different interfaces and types。
If you were to add the sample XML into the configuration file and run the application;
you would get a configuration initialization failure。 That’s because the XML node is not a
standard configuration item and thus needs custom parsing。 And when you want custom parsing;
you need to tell the configuration infrastructure what code to execute。 The following is
the plete configuration file with custom processing tags。