Динамическая загрузка DLL - PullRequest
8 голосов
/ 26 февраля 2011

У меня есть программа, которая должна использовать большое количество плагинов.

Каждый плагин должен поддерживать очень простой интерфейс, этот интерфейс определен в DLL (IBaseComponent для простоты ради вопроса).

Каждый плагин будет находиться в определенном каталоге (AppDirectory \ plugin \ plugin-type).Каждый плагин может иметь любое имя для dll плагина (AppDirectory \ plugin \ plugin-type \ plugin-name.dll).

Поэтому мне нужно проверить каждый подкаталог плагина, найти каждый плагин, который имеет класс, которыйподдерживает интерфейс IBaseComponent, создает экземпляр класса и вызывает некоторые функции на подключаемом модуле.

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

Каждый плагин должен иметь файл Base.dll в отдельных папках плагина (а не только в программе, которая будет загружать плагин).и также кажется, что я получаю много ошибок и предупреждений о динамической загрузке DLL, которые имеют DLL, которые также должны быть загружены.

Я использую:

pluginModule = System.Reflection.Assembly.ReflectionOnlyLoadFrom(PathToAssembly);

, чтобы захватитьПлагин DLL и использование:

types = moduleAssembly.GetTypes();

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

if (type.GetInterface("FrameworkNameSpace.IBaseComponent") != null)
    //it's of the IBaseComponent interface

Позже, чтобы фактически создать экземпляр класса.из dll я использую:

pluginModule = System.Reflection.Assembly.LoadFrom(PathToAssembly);

и затем использую:

types = component.GetTypes();

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

Проблема возникает, когда я использую:

types = component.GetTypes();

При попытке загрузить класс, а не просто смотреть на него.(Следовательно, мое различное использование LoadFrom и ReflectionOnlyLoad )

Исключение, которое я получаю при вызове GetTypes (при втором подключаемом модуле, но никогда не первом!):

{"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information."}

Со свойством LoaderExceptions как:

{"The specified module could not be found. (Exception from HRESULT: 0x8007007E)":null}

Я не уверен, почему это происходит.DLL находится в папке плагина, а DLL, содержащая интерфейс IBaseComponent, также находится в каждом из каталогов плагина.Я поступаю неправильно?

Кроме того, требуется ли мне хранить копию библиотеки DLL, содержащей IBaseComponent, в каждом подкаталоге плагина, а также копию, используемую самой программой, или я что-то делаюнеправильно, что позволило бы мне удалить это требование?

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

1 Ответ

5 голосов
/ 26 февраля 2011

Это ошибка LoadLibrary (). Мне кажется, что ваши плагины зависят от некоторых неуправляемых библиотек DLL. Да, Windows будет трудно найти эти библиотеки DLL, поэтому нет причин искать их в каталогах плагинов. Может быть, это работает в первый раз, потому что каталог по умолчанию вашего приложения установлен на правильный каталог. Который также будет обходным путем, используйте Environment.CurrentDirectory.

Ключевым является выяснение, какие именно зависимости не могут быть найдены. Неуправляемые файлы не будут отображаться в файле fuslogvw.exe, вы можете извлечь его из трассировки из утилиты SysInternals ProcMon.

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