Блок. GetTypes () - ReflectionTypeLoadException

Мы реализуем сменную платформу для нашего приложения и загружаем сменные блоки с помощью блока. Loadfrom. Мы затем используем GetTypes () и далее исследуем типы с каждым сменным файлом для поддерживаемых Интерфейсов.

Путь для плагинов обеспечивается пользователем, и мы циклически повторяемся через каждый из файлов в папке, чтобы видеть, поддерживает ли это (плагин) наш сменный интерфейс. Если это делает, мы создаем экземпляр, если не мы переходим на следующий файл.

Мы создаем две версии программного обеспечения от одной кодовой базы (appA_1 и appA_2).

Загрузка плагинов работает хорошо, когда плагины загружаются приложением, которое было создано в то же время, что и сменный файл. Однако, если мы создаем appA_2 и указываем на сменную папку appA_1, мы получаем исключение, когда GetTypes () называют.

Базовая версия нашего кода;

var pluginAssembly = Assembly.LoadFrom(FileName);    
foreach (var pluginType in pluginAssembly.GetTypes())
{

Мы получаем исключение "ReflectionTypeLoadException".

Это касается, потому что мы хотим, чтобы наше приложение смогло загрузить типы любого плагина, созданного любым. Есть ли что-то, что мы пропускаем?

Править: После итерации через LoaderExceptions мы обнаружили, что существует единственный файл libPublic.dll, который генерирует Систему. Исключение IO.FileNotFoundException. Странная вещь состоит в том, что этот файл находится в каталоге приложения, и на плагин ссылаются в файл проекта.

РЕДАКТИРОВАНИЕ 2: В журнале исключения мы находим, что следующее "Сравнение имени сборки привело к несоответствию: Число Пересмотра"

14
задан H.B. 6 September 2012 в 15:08
поделиться

1 ответ

Несколько вещей:

  • Убедитесь, что у вас нет повторяющихся сборок в каталоге подключаемых модулей (т.е. сборок, которые вы уже загружаете в основной app из каталога вашего приложения.) В противном случае, когда вы загружаете свой плагин, он может загрузить дополнительную копию той же сборки. Это может привести к забавным исключениям, например:

    Объект (типа «MyObject») не относится к типу «MyObject».

  • Если вы получаете исключение при создании экземпляра типа, вам может потребоваться обработать AppDomain.AssemblyResolve :

     private void App_Startup (object sender, StartupEventArgs e) 
     {{ {1}} // Поскольку мы будем динамически загружать сборки во время выполнения, 
     // нам нужно добавить соответствующий путь разрешения 
     // В противном случае произойдут такие странные вещи, как невозможность создания экземпляров TypeConverters { {1}} AppDomain.CurrentDomain.AssemblyResolve + = CurrentDomain_AssemblyResolve; 
    } 
     
    частная сборка CurrentDomain_AssemblyResolve (отправитель объекта, аргументы ResolveEventArgs) 
     {
    var domain = (AppDomain) sender; 
     
    foreach (сборка var в domain.GetAssemblies ()) 
     {
    if (assembly.FullName == args.Имя) 
     {
    вернуть сборку; 
    } 
    } 
     
    вернуть null; 
    } {{1 }} 

Я понимаю, что немного странно сообщать CLR, что для разрешения сборки нужно найти сборку с именем, которое мы используем для разрешения, но я видел странные вещи, происходящие без него. Например, я мог бы создать экземпляры типов из сборки подключаемого модуля, но если бы я попытался использовать TypeDescriptor.GetConverter , он не нашел бы TypeConverter для класса, даже если бы мог видеть атрибут Converter в классе.


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

15
ответ дан 1 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: