Ссылка на загруженную сборку - PullRequest
1 голос
/ 03 августа 2011

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

загружено: mscorlib, версия = 4.0.0.0, культура = нейтральная, PublicKeyToken = b77a5c561934e089
еще много сборок ...
загружено: ClientManager, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = ноль
загружен: вычисления, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = ноль
Имя загружаемой сборки: ClientManager, Версия = 1.0.0.0, Культура = нейтральная, PublicKeyToken = ноль
Запрошено из: Расчеты, Версия = 1.0.0.0, Культура = нейтральная, PublicKeyToken = null

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

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

Привет,
Skalli

1 Ответ

2 голосов
/ 06 сентября 2011

Ваша проблема очень похожа на ту, с которой я столкнулся при разработке плагина: Где Visual Studio ищет сборки? .

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

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

В конце концов, я решил свою проблему с помощью события 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...