按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
〃) is not a listed type〃))
End If
Dim info As ConfigurationInfo = _availableTypes。Item(identifier)
Dim assemblyName As AssemblyName = _
AssemblyName。GetAssemblyName(info。AssemblyName)
Console。WriteLine((〃assemblyname(〃 & assemblyName。ToString() & 〃)〃))
Return DirectCast( _
Assembly。Load(assemblyName)。CreateInstance(info。TypeName); _
RequestedType)
End Function
Look at the declaration of the method Instantiate(); and you will see that it is a
generics method (discussed in Chapter 11)。 The idea is to instantiate a type and perform an
automatic cast to the request type。 It avoids needing to define Instantiate() using the Object
…………………………………………………………Page 346……………………………………………………………
324 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
type。 The parameter identifier is a string that is used to search the Dictionary data member
_availableTypes。 If the identifier exists in _availableTypes; the ConfigurationInfo instance is
retrieved and used to instantiate the type。 If the identifier does not exist; an exception is thrown。
The bolded code is the special code because it is unlike what you have encountered thus
far in the book。 Built into is the ability to dynamically execute code; as illustrated here。
The first bolded line makes the reflection ability available; and the second is used to load the
assembly。 So; for example; if the parameter identifier equaled Impl1 (remember; this is one
of the keys in the configuration file element); the first bolded line would refer
ence and dynamically load the assembly Implementations1。dll。 However; and here is the
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。