5,696,576 members and growing! (14,562 online)
Email Password   helpLost your password?
Languages » C# » General     Intermediate

Dynamically load a class and execute a method in .NET

By Gary Dryden

Dynamically load a class and execute a method.
C#, Windows, .NET, Visual Studio, Dev

Posted: 10 Apr 2006
Updated: 10 Apr 2006
Views: 39,066
Bookmarked: 70 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
13 votes for this Article.
Popularity: 4.23 Rating: 3.80 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
4 votes, 30.8%
3
1 vote, 7.7%
4
8 votes, 61.5%
5

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

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:

// 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

About the Author

Gary Dryden



Occupation: Software Developer (Senior)
Location: Canada Canada

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 16 of 16 (Total in Forum: 16) (Refresh)FirstPrevNext
Generalcreate addinsmemberpune19:44 22 Jul '08  
Generalpassing parameter to classmemberFairuz Azah22:16 13 Jul '08  
GeneralPassing parameters to methodmemberKPTAN23:50 21 Feb '08  
GeneralRe: Passing parameters to methodmemberGary Dryden14:21 22 Feb '08  
GeneralRe: Passing parameters to methodmemberKPTAN0:06 23 Feb '08  
GeneralBug!memberchrkorn4:00 22 Feb '07  
QuestionReload!memberbassist3:52 6 Feb '07  
QuestionNice. How does this handle "hot swap"?memberpakora14:31 16 Jan '07  
GeneralWhere are the using's for the projectmemberapenaek6:27 9 May '06  
GeneralRe: Where are the using's for the projectmembertempsh23:22 18 May '07  
GeneralLittle enhancementmemberkornman0016:47 12 Apr '06  
GeneralRe: Little enhancementmemberGary Dryden2:45 13 Apr '06  
GeneralWhy walk types in the assembly?memberStephen Kelley17:14 11 Apr '06  
GeneralRe: Why walk types in the assembly?memberGary Dryden2:43 13 Apr '06  
GeneralExcellentmemberHEROSP11:47 10 Apr '06  
GeneralRe: ExcellentmemberGary Dryden3:33 11 Apr '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 10 Apr 2006
Editor: Smitha Vijayan
Copyright 2006 by Gary Dryden
Everything else Copyright © CodeProject, 1999-2008
Web20 | Advertise on the Code Project