梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈��梓囚徒貧議 Enter 囚辛指欺云慕朕村匈��梓囚徒貧圭�鮗� ● 辛指欺云匈競何��
!!!!隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��
catch�察�the assembly can be loaded dynamically only if Implementations1。dll exists in the local
directory or the GAC。 As an alternative�察�you could specify the entire path in the definition of the
assembly。 The downside to this strategy is that your assembly must always be located at the
same place on different machines。
When the code assigns the variable assemblyName�察�it is to a reference of a loaded
assembly。 The assembly will be parsed�察�and from there�察�it is possible to instantiate a type。 The
second bolded line calls the method CreateInstance�┌��察�with the name of the type that you want to
instantiate�察�including the namespace。 So�察�for example�察�if Implementations1。dll has been loaded�察 �
you could instantiate the type Implementations1。Implementation。 The instantiation will work
even though Implementations1。Implementation is a private class�察�because you are using dynamic
programming principles。
However�察�being able to instantiate the type does not imply being able to use the type。 To
be able to use the instantiated type�察�you need to be able to cast to a type that has been declared
publicly。
We will continue the Implementations1。Implementation example and figure out how to
instantiate and manipulate the instantiated object。 But before we get to that code�察�we need to
talk about an additional programming feature�此�singletons。
Using Singletons
The class ConfigurationManager is a shared class in terms�察�which means that you cannot
instantiate the class。 In Visual Basic´speak�察�a shared class is a module�察�and a shared method is
a method marked Shared。 A module�察�shared methods�察�and shared data members result in a
single´instance class。 Another way to get the same effect is to create a singleton。 A singleton
behaves like a shared class�察�except that the class is instantiated。 An advantage of using the
singleton approach is that you can have multiple singletons of the same type�察�whereas with the
shared class�察�there can be only a single shared class。
Consider that locks have keys�察�and sometimes a lock has a single key。 Think of the single
key as a shared class。 If that key is to open a vault�察�you will most likely want only one person to
have a key。 But what if the key is to your house door�拭�You would probably want multiple copies�察 �
but you will want to control who has those keys。 So�察�maybe you will have a single house key�察�
or maybe you will have multiple house keys�察�but you will always be in control。 The house key
example is analogous to the use of a singleton。 You could argue that a singleton could just as
well be used to open a vault�察�since you can create a single key。 But the problem with a singleton
is that using properly written source code�察�you could instantiate a second or third instance of
the singleton。 If you use a shared class�察�then source code cannot instantiate a second instance�察 �
thus enforcing a certain programming style。
´´´´´´´´´´´´´´´´´´´´´´Page 347´´´´´´´´´´´´´´´´´´´´´´´
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 325
Let¨s define the class ConfigurationLoader as a singleton�察�which implies two things�此�
o The creation of a property called Instance that references a single instance of
ConfigurationLoader。
o The constructor of ConfigurationLoader as private�察�implying that only
ConfigurationLoader can instantiate an instance of ConfigurationLoader。 This ensures
that ConfigurationLoader has similar behavior to a shared class in that the consumer
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 arc