Ссылочные несоответствия или: как я научился перестать беспокоиться и любить ILDASM
Гм, кашель,
Задача
Ник
Из перечитывания вашего исходного поста становится ясно, что у вас есть проблема с несогласованностью версий dll. То есть, по крайней мере, один проект в вашем решении зависит от Mcrcsip.Web версии X, и, по крайней мере, один проект в вашем решении зависит от Mcrcsip.Web версии Y [или, что еще хуже, зависит от библиотеки, которая зависит от Mcrcsip.Web версии Y ]. Отследить их может быть сложно и утомительно.
См. Рекомендуемое решение , чтобы пропустить до конца.
Как
Такое несоответствие возникает, когда
- у вас есть зависимость, такая как A зависит от B и C, B зависит от C,
- A и B изначально построены против C ver 1,
- A обновлено и построено для C ver 2,
вопреки тому, что мы интуитивно ожидаем, B не будет автоматически обновляться для использования C ver 2 при построении A. И A, и B должны ссылаться на одну и ту же библиотеку для построения должным образом. Таким образом, либо A должно соответствовать C ver 1, либо B должно быть перестроено и соответствовать C ver 2.
Теперь, это может произойти в любой конфигурации проекта, поэтому важно сделать версию вашего программного обеспечения [поверьте мне, эта проблема усугубляется без надлежащего подписывания \ контроля версий] и хорошо общаться в вашей команде всякий раз, когда происходит обновление зависимостей.
Стоит также знать, что есть два вида ссылок на зависимости, жесткие и мягкие [на самом деле они одинаковы, то есть ссылки на dll, за исключением того, что один является частным случаем другого, и концептуально он помогает различать два].
Жесткие ссылки
Жесткая ссылка - это зависимость проекта от статической DLL. То есть зависимость была построена в определенное время и никогда не будет обновляться, если ее физический файл не будет заменен новым. Жесткие ссылки добавляются в решение с помощью диалогового окна «Добавить ссылки» и добавления ссылки на вкладках .Net, COM или «Обзор». Жесткие ссылки, как правило, используются для добавления зависимостей к программному обеспечению, разработанному за рамками текущего решения [то есть, фреймворк, сторонние продукты и другие сторонние продукты, разработанные другими внутренними группами]. Жесткие ссылки также имеют тенденцию становиться устаревшими, потому что они поддерживаются и обновляются их собственным потоком разработки.
Предположим, сценарий выше
- у вас есть зависимость, такая как A зависит от B и C, B зависит от C,
- A и B изначально построены против C ver 1,
- A обновлено и построено для C ver 2,
Далее, предположим, что A и B находятся в одном решении
- SimpleSolution
- A
- B [Жесткая ссылка]
- C v2 [Жесткая ссылка]
- B
Когда A построено, вы получите ошибку, которую вы описали. A ожидает объект от C v2, но, поскольку B жестко зависит от C v1, C v1 сначала загружается в память, и возникает коллизия. A ожидает v2 и находит v1. Это ваша ошибка.
Чтобы разрешить эту ситуацию, вы должны
- Обновить жесткую ссылку на проект B C v1 до C v2
- Принудительное перестроение проекта B
- Обновление проекта A жесткая ссылка B на [недавно построенный] B
- Принудительное восстановление A
Мягкие ссылки
Мягкая ссылка - это зависимость проекта от другого проекта в том же решении. То есть зависимость перестраивается каждый раз, когда перестраивается все решение. Мягкие ссылки добавляются в решение с помощью диалога Добавить ссылки и добавления ссылки на вкладке Проекты. Мягкие ссылки обычно используются для добавления зависимостей к программному обеспечению, разработанному в рамках текущего решения, они имеют основное преимущество в распространении изменений , поскольку они вносятся для потребителей в рамках одного решения. В силу этого факта, мягкие ссылки не могут быть устаревшими.
[это особый случай жесткой ссылки, Visual Studio добавит ссылку, указывающую на выходной путь целевого проекта, я считаю, что он также обновляет этот путь, если целевой проект меняет свою выходную конфигурацию - но очень удобная функция, которая требует различия]
Предположим, сценарий выше
- у вас есть зависимость, такая как A зависит от B и C, B зависит от C,
- A и B изначально построены против C ver 1,
- A обновлен и построен на C ver 2,
Далее, предположим, что A и B находятся в одном решении
- SimpleSolution
- A
- B [Мягкая ссылка]
- C v2 [Жесткая ссылка]
- B
Когда будет построен A, вы получите ошибку, которую вы описали. A ожидает объект от C v2, но, поскольку B жестко зависит от C v1, C v1 сначала загружается в память, и возникает коллизия. A ожидает v2 и находит v1. Это твоя ошибка.
Для разрешения
- Обновить жесткую ссылку на проект B C v1 до C v2
- Принудительное восстановление A
Как вы видите, мягкие ссылки легче поддерживать.
IL DASM [Промежуточный язык DisASeMbler]
Теперь, когда вы узнали немного больше о ссылках и обслуживании проекта, как именно вы определяете состояние вашей сборки? В конце концов, любой ваших проектов или их зависимостей может быть несовместимым.
Самый простой способ - открыть выходной каталог вашей сборки и проверить манифест сборки каждого dll, созданного вашим решением.
Чтобы проверить манифест сборки,
- открыто
ildasm.exe
- Для VS2010 ildasm доступен с ярлыка
- Для VS2008 и VS2005 откройте командную строку Visual Studio, введите в командной строке «ildasm»
- открыть dll,
- нажмите Файл -> Открыть или
- нажмите Ctrl-O или
- перетащите свою DLL в
ildasm
окно
- открыть манифест
- дважды щелкните узел красного треугольника с надписью MANIFEST
- найти ссылки на Mcrcsip.Web
- нажмите Найти и введите Mcrcsip.Web в диалоговое окно, или
- нажмите Alt-F и введите Mcrcsip.Web в диалоговое окно, или
- проверить содержимое файла MANIFEST вручную
- проверить номер версии
Это утомительно и больно, но если вы столкнулись с [нетривиальной] ошибкой несогласованности dll, это единственный способ ее найти
Рекомендуемое решение
- Убедитесь, что ваше решение использует мягкие ссылки, где это применимо,
- развернуть Mcrcsip.Amwa.CrFactory
- развернуть Список литературы
- удалить ссылку Mcrcsip.Amwa.Core
- открыть диалоговое окно добавления ссылок
- открыть Mcrcsip.Amwa.Core на вкладке "Проекты"
- развернуть Mcrcsip.Amwa.PdfFormHandler
- развернуть Список литературы
- удалить ссылку Mcrcsip.Amwa.Core
- открыть диалог добавления ссылок
- открыть Mcrcsip.Amwa.Core на вкладке "Проекты"
- развернуть Mcrcsip.Amwa.Web
- развернуть Список литературы
- удалить ссылку Mcrcsip.Amwa.Core
- удалить ссылку Mcrcsip.Amwa.CrFactory
- удалить ссылку Mcrcsip.Amwa.PdfFormHandler
- открыть диалог добавления ссылок
- открыть Mcrcsip.Amwa.Core на вкладке "Проекты"
- открыть Mcrcsip.Amwa.CrFactory на вкладке "Проекты"
- открыть Mcrcsip.Amwa.PdfFormHandler на вкладке "Проекты"
- Убедитесь, что ваше решение использует свежие жесткие ссылки, где это применимо,
- развернуть Mcrcsip.Amwa.Core
- развернуть Список литературы
- удалить ссылку Mcrcsip.Aws.Bol
- удалить ссылку Mcrcsip.Common
- удалить ссылку Mcrcsip.Web
- открыть диалог добавления ссылок
- открыть Mcrcsip.Aws.Bol на вкладке Обзор [всегда лучше указать местоположение]
- открыть Mcrcsip.Common на вкладке Обзор
- открыть Mcrcsip.Web на вкладке "Обзор"
- развернуть Mcrcsip.Amwa.CrFactory
- развернуть Список литературы
- удалить ссылку Mcrcsip.Web
- открыть диалог добавления ссылок
- открыть Mcrcsip.Web на вкладке "Обзор"
- развернуть Mcrcsip.Amwa.PdfFormHandler
- развернуть Список литературы
- удалить ссылку Mcrcsip.Web
- открыть диалог добавления ссылок
- открыть Mcrcsip.Web на вкладке "Обзор"
- развернуть Mcrcsip.Amwa.Web
- развернуть Список литературы
- удалить ссылку Mcrcsip.Aws.Bol
- удалить ссылку Mcrcsip.Common
- удалить ссылку Mcrcsip.SharePoint
- удалить ссылку Mcrcsip.Web
- открыть диалоговое окно добавления ссылок
- открыть Mcrcsip.Aws.Bol из вкладки Обзор
- открыть Mcrcsip.Common на вкладке Обзор
- открыть Mcrcsip.SharePoint из вкладки Обзор
- открыть Mcrcsip.Web на вкладке "Обзор"
- Сложение
Если вы все еще сталкиваетесь с ошибками на этом шаге, тогда вы знаете, что один или все из
- Mcrcsip.Aws.BOL
- Mcrcsip.Common
- Mcrcsip.SharePoint
разделяет вашу зависимость от Mcrcsip.Web и ссылается на старую версию. Если это так, то для каждой жесткой ссылки, указанной выше
- выберите ссылку
- нажмите F4
- копировать содержимое из свойства Path
- диалог открытия файла в
ildasm
- вставить в имя файла
- проверять манифест
Убедитесь, что вы делаете это для всех и каждого из трех жестких ссылок выше. как только вы определите, какое подмножество из этих трех ссылается на старую версию Mcrcsip.Web, вы можете найти этот проект, обновить его жесткую ссылку, перестроить его, а затем, наконец, обновить ваш Жесткая ссылка, восстановить и вуаля. Боб твой дядя.
Уф.
Le fin
PS извиняюсь за многословие. это не очень сложная проблема, но, как я уверен, вы согласитесь, в ней много деталей. Я действительно надеюсь, что это поможет. спасибо за ваше сотрудничество тоже:)
PPS Кстати, из ваших комментариев я делаю вывод, что оригинальный разработчик использовал жесткие ссылки везде [то есть даже в рамках одного и того же решения]. возможно, у него были свои причины, но имо, это осел.