Несовместимость версии Newtonsoft Json.NET(DLL-ад)

Newtonsoft.Json выпускает несовместимые версии с таким же строгим именем, изменяя только версию файла.

По данным MSDN:

Сборки с одинаковым строгим именем должны быть идентичны.

Из-за этого наше приложение ломается, если другие приложения, находящиеся вне нашего контроля, помещают в GAC другую версию Newtonsoft.Json.dll.

Есть ли способ заставить .NET загрузить нужную нам версию?

Обновить:

Позвольте мне объяснить проблему более подробно:

Насколько мне известно, в .NET нет механизма разрешения сборок до того, как CLR попытается разрешить их и завершится неудачно.

Существует только событие AppDomain.AssemblyResolve, которое запускается только тогда, когда сборка не разрешена. Обычно этого достаточно.

Но в случае с Newtonsoft.Json он не пропускает сборку, а просто загружает неправильную.

Это происходит потому, что Newtonsoft.Json выпускает несовместимые версии с таким же строгим именем.

Пример:

Допустим, наше приложение скомпилировано против NJdll (сборка версия 1.0, файл версия 1.0)

Затем какое-то другое приложение, поместите другую несовместимую версию того же самого DLL в GAC NJdll (сборка версия 1.0, файл версия 1.1)

Поскольку они изменяют только версию файла и не изменяют версию сборки, эти две сборки имеют одинаковое строгое имя.

Так что для нашего приложения .NET, пытающегося разрешить NJdll (сборочная версия 1.0), он видит DLL в GAC и загружает ее. (Потому что .NET всегда предпочитает сборку из GAC для сборки из папки "bin")

Но загруженная сборка неверна. Он имеет версию 1.1 файла и не совместим с версией 1.0.

Поскольку обе сборки имеют одинаковую версию сборки,.NET не видит никакой разницы между ними. Но затем, когда он действительно пытается разрешить некоторый класс или член внутри, он терпит неудачу, потому что он был изменен в версии 1.1.

И все приложение терпит неудачу с непредсказуемыми ошибками.

И хуже всего то, что даже если мое приложение не помещает newtonsoft.json.dll в GAC, какое-то другое приложение, вне моего контроля, поместит в GAC другую версию newtonsoft.json.dll - мое приложение сломается с непредсказуемым исключения.

Итак, мой вопрос, могу ли я как-то загрузить правильную сборку до того, как загрузит .NET неправильную?

Обновить

https://github.com/JamesNK/Newtonsoft.Json/issues/615 https://github.com/JamesNK/Newtonsoft.Json/issues/1001

Проблемы, связанные с этой проблемой, были закрыты комментарием, который показывает, что автор Newtonsoft.Json не понимает версии .NET и почему это важно.

Ответы

Ответ 1

Загрузчик сборок будет только проверять отсутствующие сборки, т.е. сборки, которые еще не загружены. Если вы разворачиваете DLL в папку установки приложения, то загружаете ее явно при запуске приложения, тогда загрузчик сборок не будет пытаться загрузить его снова из GAC.

Вы можете загрузить сборку явно с помощью метода Assembly.LoadFrom.

Подробнее см. https://msdn.microsoft.com/en-us/library/dd153782(v=vs.110).aspx.