Загрузка 2-х версий сборки во время выполнения

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

У меня есть две сборки (ZA и ZB), обе из которых указывают на общий проект / dll (ZC), но могут быть в другой версии (то есть с тем же именем dll, одинаковыми пространствами имен, некоторые классы могут отличаться). Каждая сборка работает сама по себе, однако, если одна из них загружается другой во время выполнения (например, A загружает B), я не могу заставить ее работать. Нужна помощь.

Вот установка:

  • ZA зависит от ZC (common) версии 1.1
  • ZB зависит от версии ZC 1.0

ZA необходимо загрузить, необходимо загрузить что-то в ZB (который зависит от ZC) во время выполнения.

ZA - это главное приложение. Под его каталогом bin есть каталог плагинов plugins/plugin-ZB, в который я хотел бы поместить все ZB и его зависимости (ZC).

Вот что я пробовал до сих пор:

Assembly.Load() использовала ту же версию dll - работала нормально.

Assembly.Load() с использованием разных версий dll - ZB загружается, но при запуске метода я получаю исключение «Метод не найден».

AppDomain.Load() получил ошибку "файл не найден"; Я даже использовал делегат для разрешения сборок.

Некоторые подробности относительно ZC: - некоторые методы являются общедоступными статическими (некоторые нет). Например. Log.Log("hello"); - некоторые могут возвращать значения (примитивы или объекты). - некоторые методы нестатичны (и возвращают значения).

Помощь? - TIA


person Community    schedule 27.07.2009    source источник


Ответы (3)


    m_Assembly1 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "Old Version\Some.dll"))
    m_Assembly2 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "New Version\Some.dll"))

    Console.WriteLine("Old Version: " & m_Assembly1.GetName.Version.ToString)
    Console.WriteLine("New Version: " & m_Assembly2.GetName.Version.ToString)

    m_OldObject = m_Assembly1.CreateInstance("FullClassName")
    m_NewObject = m_Assembly2.CreateInstance("FullClassName")

С этого момента я использовал позднее связывание и / или отражение для запуска моих тестов.

.NET: загрузить две версии одной и той же библиотеки DLL

person Jonathan Allen    schedule 03.03.2010
comment
Отличный совет! не знал этого - person Gian Marco; 06.12.2014

Помимо отличного совета Джонатана Аллена, более «классический» способ решить проблему - это загрузить 2 версии в 2 разных AppDomanis. Затем вы можете использовать .NET Remoting, чтобы установить связь между двумя доменами приложений. Таким образом, ZA должен создать новый домен приложений, загрузить в этом домене приложений ZB и вызвать некоторую операцию в ZB через удаленное взаимодействие.

Обратите внимание, что .NET Remoting предъявляет некоторые требования к классам, которые вы хотите использовать (наследование от MarshalByRef), а создание AppDomain - дорогостоящая операция.

Надеюсь на эту помощь

person Gian Marco    schedule 27.07.2009
comment
У вас может быть только одна версия сборки для AppDomain - это неверно. Можно даже сослаться на две версии сборки из одной сборки, для получения дополнительной информации найдите псевдоним extern. Вот первое, что появляется в Google с примером функции: blogs.msdn.com/b/ansonh/archive/2006/09/28/ < / а> - person Graham; 06.06.2015
comment
Однако использование двух доменов приложений - это решение описанной проблемы. - person Graham; 06.06.2015

У меня были загружены две версии одной и той же сборки одновременно. Это произошло по сценарию в том виде, в каком вы его описываете.

Вы должны убедить среду выполнения загрузить одну и ту же версию ZC для ZA и ZB. Я нашел два способа сделать это:

  1. Используйте элемент bindingRedirect в файле App.config. Некоторые подробности содержатся в этом вопросе.
  2. Используйте событие AppDomain.AssemblyResolve. Некоторые подробности можно найти в этот ответ.

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

person Don Kirkby    schedule 02.03.2010
comment
Это не загрузка двух разных версий, это загрузка одной и той же версии дважды. - person Cameron MacFarland; 03.03.2010
comment
Когда у меня возникла эта проблема, @Cameron, среда выполнения загружала версию 1.1 ZC при запуске ZA. Затем, когда я загрузил подключаемый модуль ZB, среда выполнения загрузила с ним версию 1.0 ZC. Вот что я имею в виду под загрузкой двух разных версий. Чтобы ZA и ZB передавали объекты из ZC друг другу, мне пришлось заставить их обоих загружать одну и ту же версию ZC. Это то, что я описываю в своем ответе. Я неправильно понял исходный вопрос? - person Don Kirkby; 04.03.2010