1

I am using Reflection in the following manner: a) Loading the assembly b) Getting all the methods and their respective parameters c) invoking the methods

There are not issues faced while invoking methods which take input type as primitive datatypes(int,double,string etc) I tried invoking the method in 2 ways:

(object)method.Invoke(obj,respar);

where respar is an array of input parameters

object cu = Activator.CreateInstance(typeof(Customer)) as Customer;
respar.SetValue(cu, i);//i = index

and

(object)type.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Instance |  BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Default,null, obj, respar);

Where

     object obj = Activator.CreateInstance(type,true);//obj

In the first case I am getting an Argument Exception Error and in the second case I am getting Method not found Exception.

For example If I invoke a method say GetCustomer(Customer data) where Customer is a class, the above errors are thrown.

Let me explain in detail: There is one class CustomerModel

    public class CustomerModel
   {
        public string FirstName{get;set;}
        public string LastName {get;set;}
   }

And Customer Class

    public class Customer
    {
       public CustomerModel GetCustomerDetails(CustomerTable tableobj)
       {

         //TODO: Get customer details from tableobj and pass to CustomerModel Obj


       }

    }

I am trying to invoke all methods of this customer class through reflection. There is another class Test:

    public class Test
    {
       public void GetAllMethodsInassembly()
       {

          //Load assembly
          //Get all classes
          // Foreach Class=> get all methods
          //Invoke each method => get result and store in XML file
       }
    }

The method in Customer GetCustomerDetails which is throwing an exception as mentioned. Please suggest.

Pragya
  • 11
  • 2
  • Please give more details about the exceptions, preferably the whole message. Where is this Customer type defined? – Mike Zboray Jun 20 '14 at 06:35
  • Object of type 'Customer' cannot be converted to type 'Customer'. and the other one is :Method 'GetCustomer' not found. Customer Class is defined in the same assembly I mentioned – Pragya Jun 20 '14 at 06:39
  • Are you defining a Customer type in your assembly? How are you loading the assemblies? Are you dynamically loading an assembly you are also referencing? – Mike Zboray Jun 20 '14 at 06:42
  • Loading the assembly this way: `code` Assembly assembly = Assembly.LoadFile(); foreach (Type type in assembly.GetTypes()) { if (type.IsClass) { MethodInfo method = type.GetMethod(methodName); Yes Dynamically Loading the assembly using reflection – Pragya Jun 20 '14 at 06:47
  • Try LoadFrom instead of LoadFile – Mike Zboray Jun 20 '14 at 06:48
  • The class Customer is there in the assembly. Say I have to pass a customer object to the method GetCustomer. – Pragya Jun 20 '14 at 06:49
  • No luck. Same Exceptions are thrown – Pragya Jun 20 '14 at 06:51
  • So you've probably got the same assembly loaded in different binding contexts. You might be able to find something on this in my previous answers. I won't be able to post a detailed answer for a few hours. – Mike Zboray Jun 20 '14 at 07:06

2 Answers2

0

Have you tried using Type.GetMethod instead which returns a MethodInfo that has an Invoke method? More info here: http://msdn.microsoft.com/en-us/library/6hy0h0z1(v=vs.110).aspx Another alternative would be to use dynamic.

Tibi
  • 1,507
  • 1
  • 9
  • 10
0

It looks like you've referenced the assembly with the Customer type directly as well as tried to load it dynamically using Assembly.LoadFile. I would try doing something like this to get the assembly and invoke methods in it:

Assembly asm = typeof(Customer).Assembly;
foreach (Type type in asm.GetTypes()) 
{ 
    if (type.IsClass) 
    { 
        MethodInfo method = type.GetMethod(methodName);
        // TODO: create obj
        // TODO: create respar
        method.Invoke(obj, respar);
    }
}

If you insist on loading the assembly dynamically and referencing it, you've got to understand assembly binding contexts or you will keep running into the same problem.

Assembly binding contexts are isolated, in-memory assembly caches. Load (the "default"), LoadFrom, and LoadFile all use different contexts. The same type from the same assembly loaded in different context are considered different by the runtime. When a referenced assembly is loaded it is bound in the default "Load" context.

Another option may be to use the Assembly.Load and provide the assembly name. If the assembly is strong-named another option may be to Load it earlier and then use LoadFrom later, because LoadFrom will check if an assembly with the same name has already been loaded into Load context before loading it from the specified file.

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
  • I am trying to get all the methods of that assembly not only Customer. So How can I load the assembly giving typeof only as Customer or any other class when I am trying to access other classes as well. – Pragya Jun 20 '14 at 08:53
  • @Pragya `typeof(Customer).Assembly.GetTypes().Select(t => t.GetMethods())` would give you all the methods in the assembly containing Customer. There's no need to try and dynamically load the assembly if you are referencing it. – Mike Zboray Jun 20 '14 at 08:57
  • Thanks Mike. But what if I am trying to:Load the assembly => then Get all the classes => foreach(class) => invoke each method. – Pragya Jun 20 '14 at 09:02
  • @Pragya What I'm trying to tell you is you don't have to load the assembly. It is already loaded. See my edit. – Mike Zboray Jun 20 '14 at 09:09
  • Mike, So I have to create an assembly object for every class?Please note I am getting the class names as string.(from another file) – Pragya Jun 20 '14 at 10:39
  • Mike tried the way you suggested. Now its throwing object reference not set to an instance of an object – Pragya Jun 23 '14 at 10:59