Click here to Skip to main content
15,867,834 members
Articles / Programming Languages / C#
Article

Dynamically load a class and execute a method in .NET

Rate me:
Please Sign up or sign in to vote.
4.00/5 (23 votes)
10 Apr 20061 min read 224K   117   27
Dynamically load a class and execute a method.

Introduction

This code drop is part of a smash and grab series. If you're in a rush, you can just grab this code and insert it into your application, no understanding is required. When you have some time (yeah, right), you may want to review the source code.

Background

I needed to load an arbitrary class and execute some methods in it at runtime. I wouldn't know ahead of time what the class or member name was, so I couldn't use a reference in the project. Here is how I did it. Just copy/paste from the code listing below, and away you go.

The code

C#
public class DynaInvoke
{
    // this way of invoking a function
    // is slower when making multiple calls
    // because the assembly is being instantiated each time.
    // But this code is clearer as to what is going on
    public static Object InvokeMethodSlow(string AssemblyName, 
           string ClassName, string MethodName, Object[] args)
    {
      // load the assemly
      Assembly assembly = Assembly.LoadFrom(AssemblyName);

      // Walk through each type in the assembly looking for our class
      foreach (Type type in assembly.GetTypes())
      {
        if (type.IsClass == true)
        {
          if (type.FullName.EndsWith("." + ClassName))
          {
            // create an instance of the object
            object ClassObj = Activator.CreateInstance(type);

            // Dynamically Invoke the method
            object Result = type.InvokeMember(MethodName,
              BindingFlags.Default | BindingFlags.InvokeMethod,
                   null,
                   ClassObj,
                   args);
            return (Result);
          }
        }
      }
      throw (new System.Exception("could not invoke method"));
    }

    // ---------------------------------------------
    // now do it the efficient way
    // by holding references to the assembly
    // and class

    // this is an inner class which holds the class instance info
    public class DynaClassInfo
    {
      public Type type;
      public Object ClassObject;

      public DynaClassInfo()
      {
      }

      public DynaClassInfo(Type t, Object c)
      {
        type = t;
        ClassObject = c;
      }
    }


    public static Hashtable AssemblyReferences = new Hashtable();
    public static Hashtable ClassReferences = new Hashtable();

    public static DynaClassInfo 
           GetClassReference(string AssemblyName, string ClassName)
    {
      if (ClassReferences.ContainsKey(AssemblyName) == false)
      {
        Assembly assembly;
        if (AssemblyReferences.ContainsKey(AssemblyName) == false)
        {
          AssemblyReferences.Add(AssemblyName, 
                assembly = Assembly.LoadFrom(AssemblyName));
        }
        else
          assembly = (Assembly)AssemblyReferences[AssemblyName];

        // Walk through each type in the assembly
        foreach (Type type in assembly.GetTypes())
        {
          if (type.IsClass == true)
          {
            // doing it this way means that you don't have
            // to specify the full namespace and class (just the class)
            if (type.FullName.EndsWith("." + ClassName))
            {
              DynaClassInfo ci = new DynaClassInfo(type, 
                                 Activator.CreateInstance(type));
              ClassReferences.Add(AssemblyName, ci);
              return (ci);
            }
          }
        }
        throw (new System.Exception("could not instantiate class"));
      }
      return ((DynaClassInfo)ClassReferences[AssemblyName]);
    }

    public static Object InvokeMethod(DynaClassInfo ci, 
                         string MethodName, Object[] args)
    {
      // Dynamically Invoke the method
      Object Result = ci.type.InvokeMember(MethodName,
        BindingFlags.Default | BindingFlags.InvokeMethod,
             null,
             ci.ClassObject,
             args);
      return (Result);
    }

    // --- this is the method that you invoke ------------
    public static Object InvokeMethod(string AssemblyName, 
           string ClassName, string MethodName, Object[] args)
    {
      DynaClassInfo ci = GetClassReference(AssemblyName, ClassName);
      return (InvokeMethod(ci, MethodName, args));
    }
  }

Notes

This is how you use it:

C#
// Create an object array consisting of the parameters to the method.
// Make sure you get the types right or the underlying
// InvokeMember will not find the right method
Object [] args = {1, "2", 3.0};
Object Result = DynaInvoke("c:\FullPathToDll.DLL", 
                "ClassName", "MethodName", args);
// cast the result to the type that the method actually returned.

SmashGrab / Redux series

I have recently started two series of articles here at CodeProject. Smash&Grab is intended as a series of short articles on one specific code technique. Redux is intended as a series of longer articles which attempt to reduce a complicated topic (like GridView) into its basic constituent parts and show that once you have all the information, it wasn't really that hard after all. To find Smash&Grab articles, search for the keyword SmashGrab. To find Redux articles, search for the keyword Redux. I welcome any contributions to either series, but please follow the guidelines when submitting articles to either.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 4 Pin
Jay Iyengar4-Jul-16 23:05
Jay Iyengar4-Jul-16 23:05 
QuestionExcellent work Pin
kkatada27-Mar-15 18:46
kkatada27-Mar-15 18:46 
AnswerImproved and Corrected Version Pin
SBhht1-Jun-11 12:46
SBhht1-Jun-11 12:46 
GeneralRe: Improved and Corrected Version Pin
wvd_vegt2-May-12 21:51
professionalwvd_vegt2-May-12 21:51 
GeneralMy vote of 5 Pin
hdavo15-Feb-11 23:20
hdavo15-Feb-11 23:20 
QuestionHey buddy, what about writing working examples??? Pin
Mackovic14-Aug-10 8:59
Mackovic14-Aug-10 8:59 
GeneralIssue with .NET Compact Framework Pin
Arthur Walker20-Aug-09 10:05
Arthur Walker20-Aug-09 10:05 
QuestionNot able to use the first type shown [modified] Pin
Syed Aslam Basha30-Apr-09 4:39
Syed Aslam Basha30-Apr-09 4:39 
Generalcreate addins Pin
pune22-Jul-08 18:44
pune22-Jul-08 18:44 
Generalpassing parameter to class Pin
Fairuz Azah13-Jul-08 21:16
Fairuz Azah13-Jul-08 21:16 
GeneralPassing parameters to method Pin
KPTAN21-Feb-08 22:50
KPTAN21-Feb-08 22:50 
GeneralRe: Passing parameters to method Pin
Gary Dryden22-Feb-08 13:21
Gary Dryden22-Feb-08 13:21 
GeneralRe: Passing parameters to method Pin
KPTAN22-Feb-08 23:06
KPTAN22-Feb-08 23:06 
GeneralBug! Pin
chrkorn22-Feb-07 3:00
chrkorn22-Feb-07 3:00 
GeneralRe: Bug! Pin
Member 433446621-Dec-10 7:30
Member 433446621-Dec-10 7:30 
GeneralRe: Bug! Pin
igudipalli21-Dec-10 7:43
igudipalli21-Dec-10 7:43 
QuestionReload! Pin
bassist6-Feb-07 2:52
bassist6-Feb-07 2:52 
QuestionNice. How does this handle "hot swap"? Pin
pakora16-Jan-07 13:31
pakora16-Jan-07 13:31 
GeneralWhere are the using's for the project Pin
apenaek9-May-06 5:27
apenaek9-May-06 5:27 
GeneralRe: Where are the using's for the project Pin
tempsh18-May-07 22:22
tempsh18-May-07 22:22 
GeneralLittle enhancement Pin
kornman0012-Apr-06 15:47
kornman0012-Apr-06 15:47 
GeneralRe: Little enhancement Pin
Gary Dryden13-Apr-06 1:45
Gary Dryden13-Apr-06 1:45 
QuestionWhy walk types in the assembly? Pin
Stephen Kelley11-Apr-06 16:14
Stephen Kelley11-Apr-06 16:14 
AnswerRe: Why walk types in the assembly? Pin
Gary Dryden13-Apr-06 1:43
Gary Dryden13-Apr-06 1:43 
GeneralRe: Why walk types in the assembly? Pin
Jaap Faber15-Apr-09 21:09
Jaap Faber15-Apr-09 21:09 
I am not sure about this. I think this only is correct when your namespace is the same as your assemblyname.
Nice article by the way Smile | :)
Thanks, Koob.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.