2011-08-03 3 views
1

Я не уверен, как описать это лучше всего. Но у меня проблема с пониманием процесса загрузки ассемблий.
Мое приложение использует плагины через Reflection. Он работает очень хорошо, и я доволен этим. Теперь я наткнулся на проблему, которая меня смущает, и я думаю, что что-то пропустил:
В одном из моих модулей я ссылаюсь на другой модуль. Во время выполнения загружаются все модули. Существуют модули ClientManager и вызывающий модуль Calculations. ClientManager и Calculations загружены. Расчеты ссылаются на ClientManager. Когда Calculations пытается загрузить класс ClientManager, я получаю исключение File Not Found-exception.
Оба сборок загружаются из потоковых в памяти (через Assembly.Load (байты [])
Когда Расчеты пытается загрузить класс ClientManager это, как она выглядит следующим образом:.Ссылка на загруженную сборку

загружено: mscorlib, Version = 4.0.0.0, культура = нейтральной, PublicKeyToken = b77a5c561934e089
многие другие Агрегаты ...
загружен: ClientManager, Version = 1.0.0.0, культура = нейтральной, PublicKeyToken = нуль
нагруженные: Расчеты, Version = 1,0. 0.0, Культура = нейтральная, PublicKeyToken = null
Название собрания должно быть aded: ClientManager, Version = 1.0.0.0, культура = нейтральной, PublicKeyToken = нуль
Запрашиваемые из: Расчеты, Version = 1.0.0.0, культура = нейтральной, PublicKeyToken = нуль

Таким образом, сборка загружается , но он запрашивается, и запрос не выполняется. Что мне не хватает? Нужно ли загружать сборку дважды?

Я благодарен за любую помощь.

Привет,
Skalli

+0

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

+0

Они находятся в разных каталогах. Каждый модуль имеет свой собственный каталог. Меня озадачивает то, что я должен загрузить сборку, даже если она уже загружена в AppDomain. Это не большая проблема, чтобы загрузить сборку снова, но я не понимаю, почему это необходимо в этот момент. – Skalli

+0

Если Plugin1.dll ссылается на PluginHelper1.dll, тогда поместите эти два в тот же каталог, загрузите файл Plugin1.dll, и вам должно быть хорошо идти. –

ответ

2

Ваша проблема очень похожа на этот я столкнулся разрабатывающим штепсель: Where does Visual Studio look for assemblies?.

Я думаю, что вы должны прежде всего понять, где .NET ищет вашу сборку и сравнить ее с той, которая уже загружена в ваш AppDomain. Это можно сделать с помощью ProcMon.exe, чтобы узнать, где ваше приложение не может найти сборку и посмотреть на свойство CodeBase ClientManager, которое вы можете найти в AppDomain.CurrentDomain.GetAssemblies().

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

В конце концов, я решил проблему, используя событие AssemblyResolve, также просто ищу свою сборку в загружаемых в настоящее время сборках и просто обновляя ее (не загружая ее снова).

Вот как я это сделал. Я не уверен, что это очень аккуратно, так как он работает только потому сборки, не было найдено уже загружено:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    foreach (Assembly anAssembly in AppDomain.CurrentDomain.GetAssemblies()) 
     if (anAssembly.FullName == args.Name) 
      return anAssembly; 
    return null; 
} 
+0

Спасибо за ответ. Ваше решение звучит очень аккуратно, и я попробую его, как только у меня будет время. На данный момент я соглашался с ILMerge, даже если у него есть некоторые недостатки (без редактирования и продолжения, разные выходные данные проекта, чем вывод ILMerge, что является проблемой при работе с WiX ...). Могу ли я спросить, как вы вернули загруженную сборку? Я буду отмечать ваше сообщение как ответ, хотя я еще не мог его попробовать. Я обновлю свой прогресс, если попытаюсь. – Skalli

Смежные вопросы