Как загрузить сборку во время выполнения перед событием AssemblyResolve?

На самом деле я попытался реализовать какие-то «статически связанные» сборки в моем решении. Поэтому я попробовал следующее:

  • Добавление ссылки на мою сборку с помощью CopyLocal = false
  • Добавление самого DLL-файла в мое решение с помощью «Добавить в качестве ссылки»
  • Добавление самого файла DLL в мои ресурсы с помощью «Добавить ресурс» – «Добавить существующий файл»,
  • Добавление некоторого типа из моей сборки в Form1 как private MyObject temp = new MyObject();

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

 AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => { Assembly MyAssembly = AppDomain.CurrentDomain.Load(Properties.Resources.ExternalAssembly); return MyAssembly; }; 

Так что это работает! Я могу загрузить свою сборку из файла ресурсов в AssemblyResolveEvent. Но это событие происходит только в том случае, если оно не может найти мою сборку нигде. Но как я могу загрузить свою сборку до того, как .Net попытается выполнить поиск в разных местах?

Из-за фактов из проверки для ранее связанных сборок я думал, что можно будет заранее загрузить сборку в домен, и это будет принято.

Я попробовал это в program.cs, используя следующий метод Main ()

 static void Main() { LoadMyAssemblies(); AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => LoadMyAssemblies(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } private static Assembly LoadMyAssemblies() { Assembly result = AppDomain.CurrentDomain.Load(Properties.Resources.MyStaticAssembly); return result; } 

Но он все еще попадает в ResolveEventHandler. И намного лучше, если я снова загружу сборку и загляну в AppDomain.CurrentDomain.GetAssemblies (), я вижу, что моя assembly загружается дважды!

Итак, любая идея, почему моя загруженная assembly не будет учитываться при ее загрузке до события AssemblyResolve? С помощью отладчика я также вернул нуль, когда вызов пришел из AssemblyResolve, но в этом случае я получил исключение FileNotFoundException в начале.

На всякий случай, когда вы не знали, есть инструмент ILMerge из MS Research, который объединяет сборки в один файл.

Также вы можете создавать сборки с несколькими файлами, используя инструмент Assembly Linker .

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

CLR Binder не знает, что LoadMyAssemblies () делает то же самое, что и событие AssemblyResolve, и что они оба пытаются найти одну и ту же сборку и загрузить ее.

Событие AssemblyResolve всегда запускается в тот момент, когда Binder решает, что он искал все возможные местоположения (которые доступны для поиска по этому приложению) и не смог найти совпадение.

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

Я продолжу и отвечу на вопрос о том, как избежать попадания в событие AssemblyResolve. 1) Поместите сборку в GAC. Что касается Binder, то GAC всегда выигрывает. 2) Поместите свою сборку на пробный путь и убедитесь, что Binder ее подбирает (посмотрите на статью «Как среда выполнения находит сборки» в MSDN для получения дополнительной информации об этом).

  • x86_64 - Условия сборки и выход из строя
  • Как сделать kernel ​​для моего загрузчика?
  • Как сохранить сборки ASP.NET в AppDomain в живых?
  • Очень быстро memcpy для обработки изображений?
  • Самый быстрый способ вычисления 128-битного целого по модулю 64-разрядного целого числа
  • Как загрузить сборку в AppDomain со всеми ссылками рекурсивно?
  • Код C ++ для проверки гипотезы Collatz быстрее, чем assembly вручную - почему?
  • Почему медленная инструкция цикла? Не удалось ли Intel эффективно внедрить его?
  • Безопасно ли читать конец конца буфера на одной странице на x86 и x64?
  • Как скомпилировать и запустить программу C в Sublime Text 2?
  • Определите, были ли сборки .NET построены из одного источника
  • Давайте будем гением компьютера.