Использование нескольких версий одной и той же библиотеки DLL

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

Однако в моих DLL я бы хотел использовать новую версию внешней DLL (над которой я не контролирую). Если я просто ссылаюсь на новую DLL и работаю только с этим, мой код будет работать, но старый код перестанет работать.

Could not load file or assembly 'itextsharp, Version=5.0.6.0, Culture=neutral, PublicKeyToken=8354ae6d2174ddca' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) 

Я пробовал простой трюк по изменению имени DLL, но это, по-видимому, было слишком наивным для меня, чтобы думать, что это сработает. Я пробовал использовать внешние псевдонимы (определяя их в своих ссылках), но я до сих пор не знаю, как получить два файла с тем же именем в одной папке BIN …

Что мне делать?

Вы можете загрузить другую версию в конкретный AppDomain

Возможно, слишком подробно, но вот статья, демонстрирующая использование AppDomains в полезной настройке и как они работают:

http://msdn.microsoft.com/en-us/magazine/cc164072.aspx

В самом основном смысле это сводится к этому образцу кода:

  AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); ... static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { if (/*some condition*/) return Assembly.LoadFrom("DifferentDllFolder\\differentVersion.dll"); else return Assembly.LoadFrom(""); } 

Другим жизнеспособным вариантом является использование extern , как описано здесь:

http://blogs.msdn.com/b/abhinaba/archive/2005/11/30/498278.aspx

Предположим, что у вас есть структура проекта следующим образом:

Схема проекта

… где A и B – библиотеки classов, а C – проект исполняемого типа (например, единичный тест или консольный проект).

Предположим, что структура папок такова:

 ABC.sln A/A.csproj A/... B/B.csproj B/... C/C.csproj C/... lib/thirdparty4/thirdparty.dll lib/thirdparty5/thirdparty.dll 

Если бы мы попытались наивно ссылаться на наши проекты вместе, у нас возникла бы проблема: две версии thirdparty.dll будут скопированы в одну и ту же папку (каталог вывода (т. thirdparty.dll ) C ). Нам нужен способ, чтобы C копировал обе библиотеки dll в свой выходной каталог и предоставлял механизм для ссылки на один.

Чтобы решить эту проблему, я модифицировал C.csproj чтобы содержать следующее:

   PreserveNewest thirdparty4\thirdparty.dll   PreserveNewest thirdparty5\thirdparty.dll   

Это даст указание создать в своем выходном каталоге как thirdparty4\thirdparty.dll и thirdparty5\thirdparty.dll .

Теперь, после построения C , его выходной каталог выглядит следующим образом:

 C\bin\Debug\A.dll C\bin\Debug\B.dll C\bin\Debug\C.dll C\bin\Debug\thirdparty4\thirdparty.dll C\bin\Debug\thirdparty5\thirdparty.dll 

Чтобы указать C для использования обеих этих библиотек, я добавил к нему файл App.config со следующим:

                  

Это даст указание сборке, в зависимости от того, какая версия нужна, использовать одну DLL или другую, которые будут доступны в подпапках выходного каталога. (Элементы bindingRedirect не являются обязательными, но вы можете использовать их, если вам нужен ряд изменений для этого.)

Вы также можете полагаться на redirect привязки сборки для своей сильной именованной сборки, как описано в http://msdn.microsoft.com/en-us/library/2fc472t2.aspx .

У вас будет только одна версия файла (последняя), и обе ссылки разрешат ее.

Если решение AppDomains не применимо в вашем случае, вы находитесь под давлением времени, имеете противоречивые требования (как это когда-либо случается) и не возражаете против смехотворно выдуманных хаков:

  • Декомпилируйте новую версию сборки, используя инструмент ildasm (часть командной строки Developer, включенная в Visual Studio)
  • Отредактируйте сгенерированный файл .il, чтобы найти / заменить ссылки пространства имен сборки. Используя приведенный пример, это будет изменение от itextsharp.X до itextsharp.new.X
  • Аналогичным образом отредактируйте значение для атрибута AssemblyTitleAttribute. Это требует перевода символов ASCII в шестнадцатеричный.
  • Перекомпилируйте файл .il с помощью ilasm
  • Обратите внимание, что это может потребоваться повторить для любых зависимых сборок (например, someassembly.core.whatever)
  • Добавьте новые DLL-файлы в свой проект с другим именем и укажите их явно (а не через nuget или что-то еще)

Эй, не смотри на меня так. Я действительно сказал смешно надуманный взлом …

  • Возrotation константной ссылки на локальную переменную из функции
  • Могу ли я передавать параметры по ссылке в Java?
  • Содержит ли сборщик мусора статические переменные или методы в java?
  • Есть ли способ найти адрес ссылки?
  • Исключение Json и Circular Reference Exception
  • Скала и прямые ссылки
  • Каковы правила автоматического разыменования Rust?
  • Как изменить переменную, к которой относится ссылка C ++?
  • Можем ли мы переназначить ссылку на C ++?
  • В чем смысл * и & применимо к именам переменных?
  • Передача аргументов по значению или по ссылке в объекте C
  • Interesting Posts

    Получение ошибки Процедура слишком велика в макросах VBA (Excel)

    Как читать несколько текстовых файлов в одном RDD?

    В чем разница между списками параметров и несколькими параметрами в списке в Scala?

    Как отправить несколько изображений на сервер с помощью MultipartEntity от android

    Ошибка компиляции: отклонение ‘\ 302’ в программе и т. Д.

    Сохранить словарь в userdefaults в swift 3 с помощью xcode 8

    Управление порядком отображения легенды ggplot2

    Возможно ли иметь несколько аудиовыходов?

    Какая петля быстрее, пока или для?

    Как настроить систему для использования репозитория FIWARE yum?

    История удаленных программ в Windows 7

    jQuery загрузка изображений с полным обратным вызовом

    Ошибки, которые относятся к кучке неразрешенных символов OpenSSL, которые явно существуют?

    Двойной нельзя разыменовать?

    Ошибка: выполнение выполнено для задачи ‘: app: transformClassesWithDexForDebug’ в студии android

    Давайте будем гением компьютера.