Как загрузить сборку во время выполнения перед событием 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 - Условия сборки и выход из строя
  • Maven: добавьте зависимость к банке относительным путем
  • Могу ли я загрузить сборку .NET во время выполнения и создать экземпляр типа, зная только имя?
  • Почему медленная инструкция цикла? Не удалось ли Intel эффективно внедрить его?
  • Очень быстро memcpy для обработки изображений?
  • Как объединить несколько сборок в один?
  • Правильное изменение неопределенного поведения, если число больше ширины типа?
  • Вызов функции стандартной библиотеки C из asm в Visual Studio
  • Определите, были ли сборки .NET построены из одного источника
  • Проверьте, равен ли регистр нулю с помощью CMP reg, 0 против OR reg, reg?
  • Есть ли альтернатива Maven или порт для мира .NET?
  • Давайте будем гением компьютера.