Использование нескольких версий одной и той же библиотеки 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 или что-то еще)

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

  • В чем разница между ключевыми словами «ref» и «out»?
  • Почему ссылка, не связанная с константой, не может привязываться к временному объекту?
  • Странное поведение const_cast
  • c # Visual Studio ... добавление ссылок программно
  • Могу ли я передавать параметры по ссылке в Java?
  • Не удалось найти имя типа или имени пространства
  • Можно ли ссылаться на переменную со строкой и int?
  • Разница между указателем и ссылкой как параметр streamа
  • В чем смысл * и & применимо к именам переменных?
  • Скала и прямые ссылки
  • В терминах laymans, что означает «статический» в Java?
  • Давайте будем гением компьютера.