Click here to Skip to main content
Click here to Skip to main content

Run-Time Code Generation II: Invoke Methods using System.Reflection

By , 18 Jan 2006
 

Introduction

.NET provides mechanisms to compile source code and to use the generated assemblies within an application. Using these features, you can make applications more adaptive and more flexible.

This article shows how to invoke methods from an assembly using System.Reflection.

Necessary Using Statements

Before you start, add the following using statements to your application to ease the use of the namespaces:

using System.Reflection;
using System.Security.Permissions; 

Getting Started

At the beginning, you have to know which method from which type and from which module you want to call. Inspecting an assembly can be done very easily with System.Reflection too. But now we assume having all the knowledge about it because we generated it ourselves like in Run-Time Code Generation Part I.

So we just set the module's name, the type's name and the method's name:

string ModuleName = "TestAssembly.dll";
string TypeName = "TestClass";
string MethodName = "TestMethod";

Open an Assembly

Then you can open the assembly and set some Binding Flags, which are necessary for the instantiation of the chosen type:

Assembly myAssembly = Assembly.LoadFrom(ModuleName);

BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | 
  BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

Invoke a Method

After that, three loops are used to inspect the assembly and get the chosen module/type/method combination. Within the last loop, the type is instantiated and the method is called. The method can be called with parameters, but here we choose null for methods with no parameters. There can also be a response from the method, which we put into a general object.

Module [] myModules = myAssembly.GetModules();
foreach (Module Mo in myModules) 
    {
     if (Mo.Name == ModuleName) 
         {
         Type[] myTypes = Mo.GetTypes();
         foreach (Type Ty in myTypes)
             {
            if (Ty.Name == TypeName) 
                {
                MethodInfo[] myMethodInfo = Ty.GetMethods(flags);
                foreach(MethodInfo Mi in myMethodInfo)
                    {
                    if (Mi.Name == MethodName) 
                        {
                        Object obj = Activator.CreateInstance(Ty);
                        Object response = Mi.Invoke(obj, null);
                        }
                    }
                }
            }
        }
    }

Conclusion

With a few lines of code, you make your application call any method in any type from any module. In combination with code compilation, that is a powerful mechanism to enhance the adaptability of your applications.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

André Janus
Web Developer
Germany Germany
Member
I am currently student at the university of Karlsruhe and working on my master thesis at the IT-Management and Web Engineering Research Group within the institute of telematics.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWindows Form with TableLayoutPanel is changing its Controls position when is shown in mdiParent Form. How to Resolve this Issue?memberNouman_gcu21 Dec '09 - 1:16 
I have Windows Form which is implemented as per singleton pattern and having TableLayoutPanel as container on it for other controls to be placed on it and it is generating an anonymous problem regarding controls movement in which they change their position when set as mdiChildForm of a mdiParent Form. In this scenario if a windows Form is not being implemented by singleton pattern then it is working fine and if not then the Controls like lable and others are changing their location when the form appear on screen inside mdiparent second time by the user. The further detail regarding this problem is described below.
 
There are two Forms named as UI-1 and UI-2 and one Is the MDIParent Form named as MainForm.
 
Form UI-1 has the singleton pattern implementation and can only be initialized by GetInstance() method as you can see from code given below.

 
The code In the UI-1 Form:
 
public partial class UI1 : Form
    {
        private static UI1 frm;
     
        public static UI1 GetInstance()
        {
            if (frm == null)
            {
                frm = new UI1();
            }
            return frm;
        }
 
        private UI1()
        {
            InitializeComponent();
        }
 
        public void ShowLabelCoordinates()
        {
            MessageBox.Show("Location: " + this.label1.Location.ToString() + " Position: "+ 
              this.label1.PointToScreen(this.label1.Location).ToString());
        }
    }
 

Form UI-2 is with its usual constructor and can be initialized directly from it as you can see from code given below.
 
public partial class UI2 : Form
    {
        public UI2()
        {
            InitializeComponent();
        }
    }
 
The code in the main Form which is actually a mdi Parent Form.
 
UI1 frm = UI1.GetInstance();
            frm.MdiParent = this;
            frm.Show();
            frm.Focus();
            frm.ShowLabelCoordinates();
 
UI2 frm = new UI2();
            frm.MdiParent = this;
            frm.Show();
            frm.Focus();
 
Sample Application has been attached at the link given below
http://www.eggheadcafe.com/fileupload/1355103023_mdiTestApp.zip
 

Any immediate assistance will be highly appreciated.
 
Muhammad Noman
GeneralReflection , Invoke Methods using System.ReflectionmemberNouman_gcu29 Oct '09 - 3:40 
I have a Scenario in which the references of assemblies are not added to my current Visual Studio Project assembly and i need to load assembly from different paths at run time and then need to use some methods of the loaded assembly and specially in case of method overloading and overriding . I developed a sample application which is loading assembly to invoke the methods and its working fine but when I make the a method overload then its generating error. Code is given below
 
public class Addition
{
public int Add(int a, int b)
{
return a + b;
}
 
public int Add(float a, int b)
{
return (int)(a + b);
}
}

 

and reflection is
 

Assembly o = Assembly.LoadFrom("C:/dlls/TestMath.dll");
BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
 
if (o != null)
{
Module[] ms = this.o.GetModules();
 
foreach (Module m in ms)
{
Type[] types = m.GetTypes();
foreach (Type tp in types)
{
if (tp.Name == "Addition")
{
MethodInfo[] mis = tp.GetMethods(flags);
foreach (MethodInfo mi in mis)
{
if (mi.Name == "Add")
{
Object obj = Activator.CreateInstance(tp);
object[] mParam = new object[] { 5.1, 10 };
int res = (int)tp.InvokeMember("Add", BindingFlags.InvokeMethod,
null, obj, mParam);
MessageBox.Show(res.ToString());
}
}
}
}
}
}

 
Problem is here when I call method Add with above specified parameters then its showing
following Exception "Method 'TestMath.Addition.Add' not found"
 
How to play with it ?
How to read the code of an assembly at run time using reflection?
 
Someone please help me out....
 
Email: nauman_gcu@hotmail.com
GeneralMy vote of 2memberBehrooz_cs29 Jun '09 - 11:17 
you could use
return Type.getMethod(name,null).Invoke(obj);
 
i think my code is 1/27 your code.
behrooz_cs
QuestionWhat if...memberMember 22902784 Jun '08 - 23:07 
what if i need to invoke a method but..
 
1. how to dynamically invoke a method with n-numbers of parameters? am using select case to cater this prob..i counted the number of parameters needed by a called method then used a select-case ..
 
2. how to dynamically cast those parameters according to the types defined in a called method?
 
3. is it possible to supply the parameters on to an invoked method, using arrays instead?
 
example in use :
retValue = mi.Invoke(obj, New Object() {CInt(vfilter1(vfilter1.Length - 1).Trim), CObj(vStr)})
GeneralGreat article!!. But ...memberSentCleef19 Apr '07 - 1:24 
But I want to do it reverse way: I want my scripts to have access to the variables of the *PARENT* program from where the script is compilated and executed. In this way, for instance, my script would be able of changing values on the controls of the parent window.
 
Any idea?. Sigh | :sigh:
 
Thanks in advance.
GeneralRe: Great article!!. But ...memberAndré Janus19 Apr '07 - 2:15 
You can access the parent program by passing the object you want to access to the method you invoke. For example: Replace "Object response = Mi.Invoke(obj, null);" from the article with "Object response = Mi.Invoke(obj, myObject);". myObject is the object want to access.
 
Within the generated code the method(s) have to accept that object as a parameter (method signature!): For example like that: generatedMethod(myObjectType myObject). Within that method you can access the object anyway you want: For example: myObject.doSomethingWithAString("Hello World").
 
But beware of the object´s type and the methods you invoke. The generated code has to know about the type and it´s methods!
 
What you can do is something like that: The parent programm passes a button object to the generated code and the generated code can disbable or enable the button or change it´s label.
GeneralTotally coolmemberMr. VB.NET3 Nov '06 - 13:13 
Here's one reason for this, you are a person attempting to test code. You've only had the ability to test via Black Box testing techniques. This will allow one to get into the code literally. It's a way to harden applications where you aren't privy to source code debugging environments.
 
It's also the start for creating automated test cases. If you can invoke a method or control using any parms. you want, then you have 100% control over how a test case works.Laugh | :laugh:
GeneralMore Detailmemberqwerty666qwerty66628 Dec '05 - 5:09 
As in, what the heck is this actually useful for? Try writing an article, not telling us stuff we can find in MSDN. For example, why not expound on how reflection can be used to implement the visitor pattern?
GeneralRe: More DetailmemberD1113 Jun '06 - 8:41 
It can be quite useful. You can use it to allow your app to use plug-ins.
Create the plug-ins using Visual Studio with a method in it which every plugin will have and then use reflection in your app to invoke this method and therefore activate the plug-in.
GeneralRe: More Detailmembermabxsi18 Aug '06 - 4:42 
Hi,
 
Nice article. I'd like to use the reflection technology from unmanaged code, do you have any info on this ?
 
thanks
 
-mab

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 18 Jan 2006
Article Copyright 2005 by André Janus
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid