Я использую Reflection следующим образом: a) Загрузка сборки b) Получение всех методов и их соответствующих параметров c) вызов методов
При вызове методов, которые вводят тип ввода в качестве примитивных типов данных (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 (данные Клиента), где Клиент является классом, вызывается вышеуказанные ошибки.
Позвольте мне подробно объяснить: существует один класс 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
}
}
Я пытаюсь использовать все методы этого класса клиентов через отражение. Существует еще один тест класса:
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, который бросает исключение, как упоминалось. Пожалуйста, предложите.
Похоже, что вы напрямую ссылались на сборку с типом 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
("default"), LoadFrom
и LoadFile
используют разные контексты. Один и тот же тип из той же сборки, загруженной в другом контексте, во время выполнения считается другим. Когда загруженная ссылка собрана, она привязана к контексту "Load" по умолчанию.
Другим вариантом может быть использование Assembly.Load
и предоставление имени сборки. Если сборка является сильным именем другого варианта может быть Load
его раньше, а затем использовать LoadFrom
позже, потому что LoadFrom
будет проверять, если сборка с таким же именем уже загружена в Load
контекст перед загрузкой из указанного файла.
typeof(Customer).Assembly.GetTypes().Select(t => t.GetMethods())
предоставит вам все методы в сборке, содержащей Customer. Нет необходимости пытаться динамически загружать сборку, если вы ссылаетесь на нее.
Вы пытались использовать Type.GetMethod
вместо возвращающий MethodInfo
, который имеет Invoke
метод? Подробнее здесь: http://msdn.microsoft.com/en-us/library/6hy0h0z1(v=vs.110).aspx Другой альтернативой будет использование dynamic
.