Loading assemblies

In many applications, assemblies that contain types needed by an application are referenced when the application is built. It is also possible, however, to load assemblies programmatically. There are several ways to load an assembly dynamically, and each of these loading techniques returns an Assembly object that references the loaded assembly.

The first assembly loading technique uses a static assembly method called Load(). The Load() method takes a string naming the assembly to be loaded. If the named assembly cannot be found, the Load() method throws an exception. By contrast, the LoadWithPartialName() method searches both the application directory and the GAC for the specified assembly, using as much naming information as available from the caller. Listing 31-4 illustrates the difference between these two methods.

Listing 31-4: Loading Assemblies Dynamically with Load() and LoadWithPartialName(

using System; using System.Reflection; using System.IO;

public class AssemblyLoader {

private Assembly LoadedAssembly;

public AssemblyLoader(string LoadedAssemblyName, bool

PartialName) {

Console.WriteLine("+---------------------");

Console.WriteLine("| Loading Assembly {0}", LoadedAssemblyName);

Console.WriteLine("+---------------------");

if(PartialName == true) LoadedAssembly = Assembly.LoadWithPartialName(LoadedAssemblyName); else

LoadedAssembly = Assembly.Load(LoadedAssemblyName);

WritePropertiesToConsole();

catch(FileNotFoundException) {

Console.WriteLine("EXCEPTION: Cannot load assembly."); }

private void WritePropertiesToConsole() {

Console.WriteLine("Full Name: {0}", LoadedAssembly.FullName);

Console.WriteLine("Location: {0}", LoadedAssembly.Location);

Console.WriteLine("Code Base: {0}", LoadedAssembly.CodeBase);

Console.WriteLine("Escaped Code Base: {0}", LoadedAssembly.EscapedCodeBase);

Console.WriteLine("Loaded from GAC: {0}", LoadedAssembly.GlobalAssemblyCache);

public class MainClass {

static void Main(string[] args) {

AssemblyLoader Loader;

Loader = new AssemblyLoader("System.Xml, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false);

Loader = new AssemblyLoader("System.Xml", false); Loader = new AssemblyLoader("System.Xml", true);

Listing 31-4 illustrates a class called AssemblyLoader, whose constructor accepts an assembly name and a Boolean flag specifying whether the named assembly should be loaded using a partial name. The constructor loads the assembly and then calls a private method to print some of the base-naming and location properties of the loaded assembly to the console.

The Main() method in Listing 31-4 creates new objects of the AssemblyLoader class and attempts to load the .NET Framework System.XML assembly, found in the GAC, in various ways.

Executing Listing 31-4 results in the following information being written out to the console:

| Loading Assembly System.Xml, Version=1.0.3300.0, Culture=neutral, PublicKeyTok en=b77a5c561934e089 +---------------------

Full Name: System.Xml, Version=1.0.3300.0, Culture=neutral,

PublicKeyToken=b77a5

c561934e089

Location:

c:\windows\assembly\gac\system.xml\1.0.3300.0 b77a5c561934e089

\system

.xml.dll

Code Base:

file:///c:/windows/assembly/gac/system.xml/1.0.3300.0 b77a5c561934e0 8 9/system.xml.dll Escaped Code Base:

file:///c:/windows/assembly/gac/system.xml/1.0.3300.0 b77a5c 561934e089/system.xml.dll

| Loading Assembly System.Xml +---------------------

EXCEPTION: Cannot load assembly. +---------------------

| Loading Assembly System.Xml +---------------------

Full Name: System.Xml, Version=1.0.3300.0, Culture=neutral,

PublicKeyToken=b77a5

c561934e089

Location:

c:\windows\assembly\gac\system.xml\1.0.3300.0 b77a5c561934e089

\system

.xml.dll

Code Base:

file:///c:/windows/assembly/gac/system.xml/1.0.3300.0 b77a5c561934e0 8 9/system.xml.dll Escaped Code Base:

file:///c:/windows/assembly/gac/system.xml/1.0.3300.0 b77a5c

561934e089/system.xml.dll

Loaded from GAC: True

Look closely at what is happening here. In the first case, the Main() method specifies the strong name for the System.Xml assembly, including its name, public key, version information and culture specifics. Because the System.Xml assembly is in the GAC, it is not stored in the application's directory, and the Load() method is unable to find the assembly in the directory containing the executable for Listing 31-4. However, because the strong name for the assembly was specified, the Load() method has enough information to search for the assembly in the GAC. The Load() method can find the assembly in the GAC and the loading operation succeeds.

In the second case, the Main() method specifies only the base name of the System.Xml assembly. Because the System.Xml assembly is in the GAC, it is not stored in the application's directory, and the Load() method is unable to find the assembly in the directory containing the executable for Listing 31-4. In addition, the Load() method does not have enough information to locate the assembly in the GAC, as multiple instances of System.Xml might exist in the GAC with different version numbers or public keys, and the load fails.

In the third and final case, the Main() method specifies only the base name of the System.Xml assembly and instructs the loader to find an assembly using only a partial name. Again, because the System.Xml assembly is in the GAC, it is not stored in the application's directory and the LoadWithPartialName() method is unable to find the assembly in the directory containing the executable for Listing 31-4. However, the LoadWithPartialName() method takes the partially supplied name and attempts to match the name to an assembly in the GAC. Because a partial name of System.Xml is supplied, and because there is an assembly with the name System.Xml in the GAC, the load operation succeeds.

Caution Using the LoadWithPartialName() method is not recommended. If the partially named assembly has multiple copies in the GAC - perhaps with different version numbers, cultures, or public keys - the actual instance loaded may not be the expected version. In addition, the loaded instance may be a different version than the one you were expecting to load once newer versions of the assembly are loaded into the GAC. Use Load() instead of LoadWithPartialName() wherever possible.

0 0

Post a comment