 |
|
 |
Usage
Object[] classConstructorArgs = {@"OneArgForClassConstructor"};
Object[] methodArgs = {1, "2", 3.0};
Object Result = DynaInvoke.InvokeMethodSlow("c:\FullPathToDll.DLL",
"ClassName",
"MethodName",
classConstructorArgs,
methodArgs);
Class
using System;
using System.Reflection;
using System.Collections;
namespace XYZ
{
public class DynaInvoke
{
public static Object InvokeMethodSlow(string AssemblyName,
string ClassName, string MethodName, Object[] cArgs, Object[] mArgs)
{
Assembly assembly = Assembly.LoadFrom(AssemblyName);
foreach (Type type in assembly.GetTypes())
{
if (type.IsClass == true)
{
if (type.FullName.EndsWith("." + ClassName))
{
object ClassObj = Activator.CreateInstance(type, cArgs);
object Result = type.InvokeMember(MethodName,
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
ClassObj,
mArgs);
return (Result);
}
}
}
throw (new System.Exception("could not invoke method"));
}
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];
foreach (Type type in assembly.GetTypes())
{
if (type.IsClass == true)
{
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)
{
Object Result = ci.type.InvokeMember(MethodName,
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
ci.ClassObject,
args);
return (Result);
}
public static Object InvokeMethod(string AssemblyName,
string ClassName, string MethodName, Object[] args)
{
DynaClassInfo ci = GetClassReference(AssemblyName, ClassName);
return (InvokeMethod(ci, MethodName, args));
}
}
}
|
|
|
|
 |
|
 |
Hi
You have forgotten to correct the fast version. In there is also a paramaterless construtor called to instantiate the class being used.
wvd_vegt
|
|
|
|
 |
|
 |
This is exactly that I need
|
|
|
|
 |
|
 |
this code can't work.
Object Result = DynaInvoke("c:\FullPathToDll.DLL", "ClassName", "MethodName", args);
DynaInvoke is a class name, and this class has no constructor with 3 parameters.....
|
|
|
|
 |
|
 |
Excellent article – the DynaInvoke was exactly what I was looking for. However, there was a small problem when attempting to use the DynaInvoke class with the .NET Compact Framework 3.5; calling InvokeMethod causes a NotSupportedException is thrown by Type.InvokeMember. As it turns out, according to documentation on MSDN (http://msdn2.microsoft.com/en-us/library/66btctbe.aspx) "this member throws a NotSupportedException on the .NET Compact Framework".
Fortunately, there was a relatively simple work-around, as shown below:
public static Object InvokeMethod( DynaClassInfo ci,
string MethodName, Object[] args )
{
MethodInfo method = ci.type.GetMethod( MethodName );
Object Result = method.Invoke( ci.ClassObject, args );
return (Result);
}
|
|
|
|
 |
|
 |
Hi,
I have a simple dll to test which is nothing but
using System;
namespace Test
{
public class Example
{
public Example(){}
public Example(int x, int y) {}
public static int Add(int x, int y)
{
return((int)x+y);
}
}
}
Am using your first method to invoke Add method.
Invoking as
Object Result = DynaInvoke.InvokeMethodSlow(FindAssemblyToTest(clsname), clsname, methodname, args);
where args is Object[] args = { myString };
and mystring is string myString = inputFile.ReadLine();
Am reading input from file, now comes the problem it throws error message as "Add method not found"
And also error message as "Method may only be called on a Type for which Type.IsGenericParameter is true."
I tried casting,by checking each argument with in invoke method, but no luck.
memberArgs gives type of each argument.
for (int i = 0; i<= memberArgs.Length-1; i++ )
{
switch (memberArgs[i])
{
case "String":
args[i] = (args[i].ToString());
break;
case "Int16":
args[i] = Int16.Parse(args[i].ToString());
break;
case "Int32":
args[i] = Int32.Parse(args[i].ToString());
break;
case "Int64":
args[i] = Int64.Parse(args[i].ToString());
break;
case "double":
args[i] = double.Parse(args[i].ToString());
break;
case "Double":
args[i] = Double.Parse(args[i].ToString());
break;
case "float":
args[i] = float.Parse(args[i].ToString());
break;
case "long":
args[i] = long.Parse(args[i].ToString());
break;
}
}
Any help is appreciated.
modified on Thursday, April 30, 2009 11:11 AM
|
|
|
|
 |
|
 |
i want create myaddin which add code in class file ,how this can be done?
|
|
|
|
 |
|
 |
Thanks for this class. but it is possible to pass parameter(s) to 'the class' and pass another paramter to 'the method'?
_O/
/X
_|\
|
|
|
|
 |
|
 |
I have a class myDynamicClass with method MyMethod(string sParam), How can I pass a string value to myMethod using DynaInvoke class?
Thanks in advance,
Steve
Steve
|
|
|
|
 |
|
 |
Its right there at the bottom of the article:
Object [] args = {1, "2", 3.0};
Object Result = DynaInvoke("c:\FullPathToDll.DLL",
"ClassName", "MethodName", args);
|
|
|
|
 |
|
 |
Many thanks. I thought the args are pass in to "MethodName" as command line arguments. Its working now.
Regards,
Steve
KPTAN
|
|
|
|
 |
|
 |
ClassReferences should be indexed by ClassName, not AssemblyName - otherwise this won't work for different classes (it will work if you only use it for one and the same class all the time though). This needs to be changed in three places.
www.flying-cat.de
|
|
|
|
 |
|
 |
Which part of the code needs to be changed and to what?
Thank you,
|
|
|
|
 |
|
 |
Which part of the code needs to be changed and to what?
|
|
|
|
 |
|
 |
Hello,
will this code works if I need to reload the assembly?
I mean, after the assembly has been loaded, can I delete the file?]
thanks
|
|
|
|
 |
|
 |
Nice article.
I have a similar requirement kind of plugin model in ASP.net.
THere is a plugin directory where assemblies are dropped and the framework (to run assemblies) should pick it up instantiate and call a method, release the instance and then sleep. (Assemblies are derived from interface class).
The challenge I face is that once the assembly is picked up it is locked and can only be replaced by doing an IIS reset. How can this scenario be handled? I can not IISREset everytime I have to swap the plugin.
Thanks.
|
|
|
|
 |
|
 |
if you just paste the code...
Which are the missing usings??? for the project...
|
|
|
|
 |
|
 |
Late response but maybe someone else needs it now.
these references shall be added:
using System.Collections;
using System.Reflection;
|
|
|
|
 |
|
 |
Just a suggestion but:
in the signature of your InvokeMethodSlow method, declare the 'args' parameter as 'params' so that users can either pass an already created object array or variable length parameters to the function that will in turn be passed to the dynamic method.
public static Object InvokeMethodSlow(string AssemblyName, string ClassName, string MethodName, params Object[] args)
Pretty neat article
|
|
|
|
 |
|
 |
I'm planning an article update soon I'll take your suggestion into account when making it.
Thanks.
|
|
|
|
 |
|
 |
string FullTypeName = AssemblyName + "." + ClassName
Type type=TheAssembly.GetType(FullTypeName);
creates the type object directly without having to walk the types in the assembly
|
|
|
|
 |
|
 |
Thanks, I will wait for a few more comments and then make an article update.
|
|
|
|
 |
|
 |
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
Thanks, Koob.
|
|
|
|
 |
|
 |
Excellent Work.
I currently know the usage scenario for this code and i think it is very useful to me.
Can you tell us something about performance issues, about the dynamic libraries loading, especially in memory and cpu load?
Thanks
"The user really exists?,..mmm...no, it is just a legend..."
|
|
|
|
 |
|
 |
If you use the second method I describe, the library is only loaded once and it would have had to be loaded anyway if you had used a "reference".
The only penalty you pay is the dynamic method invokation rather than the direct call that would be possible if you had done early binding by referencing it in your program.
But this is the same penalty you pay when using a scripting language like vbs or javascript because these scripting languages use late binding.
|
|
|
|
 |