JAL Computing

C++COMProgramming .NET Mac Palm CPP/CLI Hobbies

 

Home
Up

Chapter 20 "Loading a Class By Name"

A problem that comes up repeatedly is how to load a class dynamically at run time given the name of the class (as a string) and the name of the assembly that contains the class (eg. AssemblyName.dll). 

Note: In a sense, the runtime fully qualified name is the assembly name pre-pended to the fully qualified class name. 

There are basically two approaches to loading a class by name. The first approach is to get a Type using one of the GetType calls:

bulletType.GetType(stringName)
bulletmyAssembly.GetType(stringName) 
bulletmyModule.GetType(stringName) 

You can then create an instance of the class by calling System.Activator.CreateInstance(myType). The second approach is to pass the name of the assembly and the fully qualified name of the class directly to System.Activator.CreateInstance.

Using Type.GetType

To use Type.GetType, you need to include the assembly name in the string as in "DrawablePlugins.Triangle,DrawablePlugIns". Here is a snippet of code that calls Type.GetType: 

 string typeName="DrawablePlugIns.Triangle,DrawablePlugIns";
 Type myType= Type.GetType(typeName);

Using myAssembly.GetType

If you have access to the assembly, you can call assembly.GetType(string).

//Assembly assembly= Assembly.GetExecutingAssembly();
Assembly assembly= Assembly.Load("DrawablePlugIns");
Type assemblyType= assembly.GetType("DrawablePlugIns.Triangle");
System.Console.WriteLine(assemblyType);

Using myModule.GetType

Finally, you can call get type on a module as in:

Module[] moduleArray= assembly.GetModules(
false);
Module myModule = moduleArray[0];
Type moduleType= myModule.GetType("DrawablePlugIns.Triangle");
System.Console.WriteLine(moduleType);

Using Activator.CreateInstance(string,string)

As mentioned, the second approach is to pass the name of the assembly and the fully qualified name of the class directly to System.Activator.CreateInstance as in: 

object oByName= System.Activator.CreateInstance("DrawablePlugIns","DrawablePlugIns.Triangle");

Note: If the class exist in the executing assembly, then you can simply pass null for the assemblyName.


Sample Project

The following example project TestLoadByName reuses the projects JALInterfaces and DrawablePlugIns which you can download from Chapter 19. You should copy the DrawablePlugIns.dll to the project folder TestLoadByName/bin/Debug. You will then need to add a reference to the JALInterfaces.dll to the TestLoadByName project. Here is the code that demonstrates how to dynamically load or instantiate a class at run time using the name of a class.

using System;
using JALInterfaces;

namespace TestLoadByName
{
    /// <summary>
    ///
Summary description for Class1.
    /// </summary>
    class Class1
    {

        /// <summary>
        ///
The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
             //
            // TODO: Add code to start application here
            //
            string typeName="DrawablePlugIns.Triangle,DrawablePlugIns";
            Type myType= Type.GetType(typeName);
            try
            {
                object oByType=System.Activator.CreateInstance(myType);
                object oByName= System.Activator.CreateInstance("DrawablePlugIns","DrawablePlugIns.Triangle");
                System.Console.WriteLine(oByType);
                System.Console.WriteLine(oByName);
            }
            catch(Exception e)
            {
                  System.Console.WriteLine(e);
            }
            System.Console.ReadLine();
        }
    }
}

Append Path to BaseDirectory

If the target dll is not in AppDomain.CurrentDomain.BaseDirectory you can append a private path to the BaseDirectory as in:

// tell app where to look for plugins
AppDomain.CurrentDomain.AppendPrivatePath("plugins");

In C# v2.0 AppendPrivatePath has been deprecated, but you can append a private path by modifying the app.config file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <probing privatePath="Plugins"/>
     </assemblyBinding>
   </runtime>
</configuration>

Hope that helps,
Jeff

Send mail to [email protected] with questions or comments about this web site. Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 © 
Last modified: 08/04/09
Hosted by www.Geocities.ws

1