Я пытаюсь обернуть голову вокруг отражения, поэтому я решил добавить возможность плагина в программу, которую я пишу. Единственный способ понять концепцию - это испачкать пальцы и написать код, поэтому я пошел по пути создания простой библиотеки интерфейсов, состоящей из интерфейсов IPlugin и IHost, библиотеки реализации подключаемых модулей классов, реализующих IPlugin, и простого консольный проект, который создает экземпляр класса реализации IHost, который выполняет простую работу с объектами плагина.
Используя рефлексию, я хотел перебирать типы, содержащиеся в моей реализации dll плагина, и создавать экземпляры типов. Мне удалось успешно создать экземпляры классов с помощью этого кода, но я не смог привести созданный объект к интерфейсу.
Я попробовал этот код, но не смог привести объект o так, как ожидал. Я прошел через процесс с отладчиком, и был вызван соответствующий конструктор. Объект Quickwatching o показал, что у него есть поля и свойства, которые я ожидал увидеть в классе реализации.
loop through assemblies
loop through types in assembly
// Filter out unwanted types
if (!type.IsClass || type.IsNotPublic || type.IsAbstract )
continue;
// This successfully created the right object
object o = Activator.CreateInstance(type);
// This threw an Invalid Cast Exception or returned null for an "as" cast
// even though the object implemented IPlugin
IPlugin i = (IPlugin) o;
Я заставил код работать с этим.
using System.Runtime.Remoting;
ObjectHandle oh = Activator.CreateInstance(assembly.FullName, type.FullName);
// This worked as I intended
IPlugin i = (IPlugin) oh.Unwrap();
i.DoStuff();
Вот мои вопросы:
- Activator.CreateInstance (Тип t) возвращает объект, но я не смог привести объект к интерфейсу, который реализовал объект. Почему?
- Должен ли я использовать другую перегрузку CreateInstance ()?
- Какие советы и хитрости связаны с отражением?
- Есть ли какая-то важная часть размышления, которую я просто не понимаю?