Как вызвать метод, который принимает входной параметр как другой объект класса, используя Reflection в C #? (Метод дает исключение аргумента)

Я использую Reflection следующим образом: а) загрузка сборки б) получение всех методов и их соответствующих параметров в) вызов методов

При вызове методов, которые принимают тип ввода как примитивные типы данных (int, double, string и т. Д.), Проблем не возникает. Я пробовал вызвать метод двумя способами:

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

где respar - массив входных параметров

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

и

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

Где

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

В первом случае я получаю ошибку исключения аргумента, а во втором - исключение "Метод не найден".

Например, если я вызываю метод GetCustomer (данные клиента), где Customer - это класс, возникают указанные выше ошибки.

Объясню подробно: есть один класс CustomerModel.

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

И класс клиентов

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

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


       }

    }

Я пытаюсь вызвать все методы этого класса клиентов через отражение. Есть еще один класс 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
       }
    }

Метод в Customer GetCustomerDetails, который, как упоминалось, выдает исключение. Пожалуйста, предложите.


person Pragya    schedule 20.06.2014    source источник
comment
Пожалуйста, опишите более подробную информацию об исключениях, желательно все сообщение. Где определяется этот тип клиента?   -  person Mike Zboray    schedule 20.06.2014
comment
Объект типа «Клиент» не может быть преобразован в тип «Клиент». а другой: Метод GetCustomer не найден. Класс клиента определен в той же сборке, о которой я упоминал.   -  person Pragya    schedule 20.06.2014
comment
Вы определяете тип клиента в своей сборке? Как вы загружаете сборки? Вы динамически загружаете сборку, на которую также ссылаетесь?   -  person Mike Zboray    schedule 20.06.2014
comment
Загружаем сборку следующим образом: code Assembly assembly = Assembly.LoadFile (‹путь к dll›); foreach (Тип типа в сборке.GetTypes ()) {if (type.IsClass) {MethodInfo method = type.GetMethod (methodName); Да Динамическая загрузка сборки с использованием отражения   -  person Pragya    schedule 20.06.2014
comment
Попробуйте LoadFrom вместо LoadFile   -  person Mike Zboray    schedule 20.06.2014
comment
Класс Customer присутствует в сборке. Скажем, мне нужно передать объект клиента методу GetCustomer.   -  person Pragya    schedule 20.06.2014
comment
Не повезло. Выбрасываются такие же исключения   -  person Pragya    schedule 20.06.2014
comment
Таким образом, у вас, вероятно, есть одна и та же сборка, загруженная в разных контекстах привязки. Возможно, вы сможете найти что-то по этому поводу в моих предыдущих ответах. Я не смогу опубликовать подробный ответ в течение нескольких часов.   -  person Mike Zboray    schedule 20.06.2014


Ответы (2)


Вы пробовали использовать вместо этого Type.GetMethod, который возвращает MethodInfo, имеющий метод Invoke? Дополнительная информация здесь: http://msdn.microsoft.com/en-us/library/6hy0h0z1%28v=vs.110%29.aspx Другой альтернативой было бы использование dynamic.

person Tibi    schedule 20.06.2014

Похоже, вы напрямую ссылались на сборку с типом Customer, а также пытались загрузить ее динамически с помощью Assembly.LoadFile. Я бы попробовал сделать что-то вроде этого, чтобы получить сборку и вызвать в ней методы:

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);
    }
}

Если вы настаиваете на динамической загрузке сборки и обращении к ней, вы должны понимать контексты привязки сборки, иначе вы столкнетесь с той же проблемой.

Контексты привязки сборок представляют собой изолированные кэши сборок в памяти. Load ("по умолчанию"), LoadFrom и LoadFile используют разные контексты. Один и тот же тип из одной и той же сборки, загруженный в разном контексте, рассматривается средой выполнения. Когда ссылочная сборка загружается, она связывается в контексте «Загрузить» по умолчанию.

Другой вариант - использовать Assembly.Load и указать имя сборки. Если сборка имеет строгое имя, другим вариантом может быть Load ее раньше, а затем LoadFrom позже, потому что LoadFrom будет проверять, была ли уже загружена сборка с тем же именем в контекст Load, прежде чем загружать ее из указанного файла.

person Mike Zboray    schedule 20.06.2014
comment
Я пытаюсь получить все методы этой сборки не только Заказчика. Итак, как я могу загрузить сборку, дающую typeof, только как Customer или любой другой класс, когда я также пытаюсь получить доступ к другим классам. - person Pragya; 20.06.2014
comment
@Pragya typeof(Customer).Assembly.GetTypes().Select(t => t.GetMethods()) предоставит вам все методы в сборке, содержащей Customer. Нет необходимости пытаться динамически загрузить сборку, если вы на нее ссылаетесь. - person Mike Zboray; 20.06.2014
comment
Спасибо, Майк. Но что, если я пытаюсь: загрузить сборку = ›затем получить все классы =› foreach (class) = ›вызвать каждый метод. - person Pragya; 20.06.2014
comment
@Pragya Я пытаюсь сказать вам, что вам не нужно загружать сборку. Он уже загружен. Смотрите мою правку. - person Mike Zboray; 20.06.2014
comment
Майк, мне нужно создать объект сборки для каждого класса? Обратите внимание, я получаю имена классов в виде строки. (Из другого файла) - person Pragya; 20.06.2014
comment
Майк попробовал то, что вы предложили. Теперь его ссылка на бросающий объект не установлена ​​на экземпляр объекта - person Pragya; 23.06.2014