Имеется основная программа, которая сначала при помощи Assembly.LoadFrom(...) загружает другую сборку из файла, а потом при помощи активатора инстанциирует объект класса, описанного в загруженной сборке. Требуется каким-то образом подцепить обработчик, находящийся в основной программе, к событию, которое время от времени генерируется объектом загруженной сборки. Как?
Дело в том, что объект, получаемый из загружаемой сборки, определяется классом, неизвестным основной программе, где сидит обработчик. То есть, я не могу написать
((MyClass)LoadedObject).NeededEvent += new MyEventHandler(MyHandler);
iT>Может тебе в общей сборке описать интерфейс с событием? iT>Точно подписчик знать тип не будет, но будет работать через этот интерфейс.
Ну, есть такой вариант, но в моём случае он будет очень и очень неудобен. Хотелось бы как то цепляться к событию практически неизвестного класса. Ведь зачем-то существует метод GetEvents?
_VC>Ну, есть такой вариант, но в моём случае он будет очень и очень неудобен. Хотелось бы как то цепляться к событию практически неизвестного класса. Ведь зачем-то существует метод GetEvents?
Тогда давай подробнее — что тебе вообще известно об этом событии?
Имя? Тип делегата?
Здравствуйте, _ViC_, Вы писали:
_VC>Ну, есть такой вариант, но в моём случае он будет очень и очень неудобен. Хотелось бы как то цепляться к событию практически неизвестного класса. Ведь зачем-то существует метод GetEvents?
Получаешь у Type EventInfo всех ивентов, на которые хочешь подписаться, а дальше вызовом EventInfo.ddEventHandler() подписывайся
M>Получаешь у Type EventInfo всех ивентов, на которые хочешь подписаться, а дальше вызовом EventInfo.ddEventHandler() подписывайся
В общем, AddEventHandler работает, но только со стандартным типом EventHandler. Если я пытаюсь подсунуть собственный делегат, то всё заканчивается исключением "не могу преобразовать тип". Вообще, мне хватит и стандартного EventHandler, но просто хочется узнать, это ограничение какое-то или я чего-то не учёл?
Здравствуйте, _ViC_, Вы писали:
_VC>В общем, AddEventHandler работает, но только со стандартным типом EventHandler. Если я пытаюсь подсунуть собственный делегат, то всё заканчивается исключением "не могу преобразовать тип". Вообще, мне хватит и стандартного EventHandler, но просто хочется узнать, это ограничение какое-то или я чего-то не учёл?
_VC>В общем, AddEventHandler работает, но только со стандартным типом EventHandler. Если я пытаюсь подсунуть собственный делегат, то всё заканчивается исключением "не могу преобразовать тип". Вообще, мне хватит и стандартного EventHandler, но просто хочется узнать, это ограничение какое-то или я чего-то не учёл?
наверное где-то кастуешь как-то не так. Показал бы код объявления делегата и обработчика.
Похоже я упёрся в то, что с созданным таким образом объектом (через Activator.CreateInstance) не удаётся осуществлять связь через нестандартные типы данных. Сначала был нестандартный EventHandler, после я попытался изменить параметр конструктора удалённого класса (string -> свой тип), что приводит к новым исключениям.
Общий вид беды таков: при использовании Activator.CreateInstance(type, new object[] {a, b, c ...}) если хотя бы один из параметров имеет нестандартный тип, то инстанциирование объекта не происходит. Как быть в таком случае?
iT>наверное где-то кастуешь как-то не так. Показал бы код объявления делегата и обработчика.
В том то и дело, что всё до безобразия просто. Код копия MSDN: определяю класс-наследник EventArgs, и определяю делегат-обработчик:
public delegate void MyEventHandler(object sender, MyEventArgs e);
Всё! Эти определения есть в обеих сборках. Но при попытке подсоединить свой обработчик, соответствующий делегату один в один, происходит исключение о невозможности преобразования типа. Я сам никакого преобразования не выполняю.
_VC>Всё! Эти определения есть в обеих сборках. Но при попытке подсоединить свой обработчик, соответствующий делегату один в один, происходит исключение о невозможности преобразования типа. Я сам никакого преобразования не выполняю.
Делегат, это такой же тип, как и все остальные, типы лежащие в разных сборках разные.
_VC>>Всё! Эти определения есть в обеих сборках.
iT>Вот и ответ. Вынеси в общую сборку.
А можно поподробнее? То есть, если у меня определён произвольный тип (он вынесен в отдельный файл) и существуют две сборки, каждая из которых использует данный тип (файл подлинкован к проекту), то получается, что если одна из сборок загружает другую. то объект этого типа в другой сборке считается объектом совершенно иного типа, нежели чем аналогичный, созданный в текущей сборке?!
А объеденить эти две сборки в третью общую я не могу по условию задачи.
Re[11]: Как обрабатывать событие из другой сборки?
_VC>>>Всё! Эти определения есть в обеих сборках. iT>>Вот и ответ. Вынеси в общую сборку.
_VC>А можно поподробнее? То есть, если у меня определён произвольный тип (он вынесен в отдельный файл) и существуют две сборки, каждая из которых использует данный тип (файл подлинкован к проекту), то получается, что если одна из сборок загружает другую. то объект этого типа в другой сборке считается объектом совершенно иного типа, нежели чем аналогичный, созданный в текущей сборке?!
Конечно. С точки зрения системы типов нет такой вещи, как "файл исходника", который компилируется в обе сборки. Каждый тип определяется абсолютно точно своим именем, включая пространство имен и полным именем (с номером версии и т.п.) сборки в которой он определен.
_VC>А объеденить эти две сборки в третью общую я не могу по условию задачи.
Еще раз. Не надо объединять этии две сборки. Надо тип, который должен быть общим — вынести в третью сборку.
Re[12]: Как обрабатывать событие из другой сборки?
iT>Еще раз. Не надо объединять этии две сборки. Надо тип, который должен быть общим — вынести в третью сборку.
Всё. Ну наконец-то я понял Спасибо, буду иметь ввиду. Хотя в моём случае проще будет не вводить один объект нового типа, а использовать несколько полей стандартного типа.