Проблемы с загрузкой зависимостей сборки динамически во время выполнения
позвольте мне попытаться объяснить мою проблему. В настоящее время я пытаюсь разработать небольшой "плагин-фреймворк", написанный на .Net (в основном для небольших экспериментов). Таким образом, идея состоит в том, чтобы иметь основное приложение, в которое можно добавлять «плагины», развертывая библиотеки DLL в определенной папке «плагины» основного приложения. Все работает нормально, плагины создаются правильно, но теперь я столкнулся с проблемой. Я развернул плагин «X», который использует дополнительные сторонние плагины, и теперь у меня есть проблема, что эти дополнительные сторонние плагины, требуемые «X», не обнаруживаются во время выполнения. Поэтому сейчас моя идея состоит в том, чтобы добавить дополнительный каталог «dependencies», в котором я также разверну все необходимые плагины.
Итак, мой первый вопрос: как я могу загрузить сборки в домен приложения (учитывая, что я знаю путь к ним), чтобы они могли использоваться моим приложением?
Я попытался подойти к этому, сделав что-то вроде:
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//find the path to the assembly and then load and return it by
//return Assembly.Load("pathToDependencies/failedAssembly.dll");
}
Проблема в том, что этот обработчик событий теперь активируется с помощью «Presentation.Zune.dll» в переменной args (я использую приложение WPF). Кажется, что эта сборка не загрузилась, но на самом деле проблема заключается в другой dll.
Может ли кто-нибудь предложить мне лучший способ решить мою проблему? Я надеюсь, что смог достаточно объяснить свою ситуацию, в противном случае просто попросите дополнительных разъяснений.
Спасибо, Юри
Ответов (3)3
Вы можете установить путь исследования среды выполнения, чтобы она могла найти сборки. Задайте элемент исследования в файле конфигурации вашего приложения.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="plugins;dependencies"/>
</assemblyBinding>
</runtime>
</configuration>
Кстати: вы можете значительно ускорить загрузку сборок, если вы кэшируете свои сборки, которые вы уже разрешили в словаре. Если A зависит от B, C и B зависит от C и вы загружаете A, AssemblyResolve будет вызываться дважды для C, и загрузка сборки только один раз будет быстрее :)
(Я не уверен, всегда ли так, что AssemblyResolve вызывается более одного раза, но я заметил это при отладке проекта один раз. И кешировать сборки не помешает ...)
AssemblyResolve
Событие происходит , когда структура пытается загрузить сборку, и выходит из строя.
Это означает, что если он дает вам Presentation.Zune.dll
в аргументах, что фреймворк не может найти эту сборку, и это ваш шанс перехватить его и сделать другие вещи, например, загрузить его из каталога, о котором фреймворк может не знать - например, ваша папка plugins \ dependencies ...
Я бы попробовал что-то вроде этого:
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if( File.Exists(".\\Plugins\\"+args.Name) ) // it's a plugin
return Assembly.Load(".\\Plugins\\"+args.Name);
else if( File.Exists(".\\Plugins\\Dependencies\\"+args.Name) ) // it's a dependency OF a plugin
return Assembly.Load(".\\Plugins\\Dependencies\\"+args.Name);
else
throw new Exception();
}