Я создал сборку, которая полагается на дополнительные сторонние сборки, которые могут быть или не быть в ссылках на проект во время добавления моей сборки. Поскольку моя сборка была первоначально построена с использованием зависимостей третьей стороны, которые, возможно, были старше, чем те, которые находятся в текущем проекте, мне нужно добавить bindingRedirects в файл app.config. Сотрудник Qaru (в ответ на вопрос о том, можно ли каким-либо образом автоматизировать поправку, требуемую для файла app.config), предложил мне рассмотреть возможность распространения моей сборки через NuGet. Это оказалось отличным предложением, но я замечаю один нечетный эффект, и я не знаю, как я мог бы его исправить, если вообще.
В папке содержимого моего пакета NuGet у меня есть файл app.config.transform, который якобы выглядит следующим образом:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="C1.Win.C1Ribbon.2" culture="neutral" publicKeyToken="79882d576c6336da"/>
<bindingRedirect oldVersion="2.0.20141.567" newVersion="Add New Value Here"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Существуют и другие переадресации, но этого должно быть достаточно, чтобы вы могли получить суть.
Когда я добавляю пакет NuGet в проект, он загружает мою сборку и изменяет файл app.config, результат, но, как это часто бывает, с программированием вещи, которые, как правило, не запускаются для планирования.
Если одна из сборок, для которых я предоставил перенаправления, уже присутствует в проекте, тогда некоторые незначительные изменения вносятся в исходный xml, который я поставил в пакете NuGet:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="C1.Win.C1Ribbon.2" culture="neutral" publicKeyToken="79882d576c6336da" />
<bindingRedirect oldVersion="0.0.0.0-2.0.20142.582" newVersion="2.0.20142.582" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Вы заметите, что oldVersion был полностью изменен, и новая версия была изменена, чтобы отразить текущую версию сборки, которая находится в ссылках на проекты. С моей точки зрения, автоматическое изменение в newVersion является дополнительным бонусом, поскольку это то, что конечный пользователь не должен делать, ОДНАКО, что изменение в oldVersion является полной катастрофой, так как проект теперь будет генерировать ошибки при компиляции.
Как я могу предотвратить замену деталей oldVersion, если сборка присутствует, когда пакет nuget добавлен в проект?
Вы действительно ошибаетесь здесь, что атрибут "oldVersion" не является источником ваших проблем. Беда началась с того, что вы зависите от другой библиотеки. Библиотеки меняются, это неизбежно. И такое изменение может и рано или поздно разорвет вашу программу. Рано в этом случае.
Автор библиотеки использует очень плохую практику. Номер версии, такой как "2.0.20142.582", не имеет смысла. Это автоматически сгенерированный номер версии. Вы можете посмотреть на такое число и не иметь абсолютно никакого представления о том, насколько эффективным может быть изменение в библиотеке. Обычная жалоба на номера версий и многие авторы библиотек переключились на семантическое управление версиями. Простейший номер версии: xyz. Если инкремент z является незначительным шагом обслуживания, о котором вы не беспокоитесь. Приращение y заставляет вас обратить внимание, вы читаете примечания к выпуску, чтобы узнать, есть ли необходимость пересмотреть или улучшить свой собственный код. Приращение x вызывает много неприятностей.
Пакеты Nuget возились с <bindingRedirect>
чтобы попытаться изменить их номер версии, не нарушая вашу программу. Немного неизбежно, потому что автор использовал такую схему нумерации бедных версий, его привязкаRedirect не имеет смысла. Он утверждает, что его новая библиотека совместима со всеми предыдущими версиями его библиотеки. Как вы выяснили, полная ложь.
Вам нужно будет выбрать, следует ли пропускать это обновление библиотеки. Если вы этого не сделаете, вы должны исправить ошибки компиляции, вызванные новой версией. Нет двух способов. Атрибут "oldVersion" не имеет значения, вы сделали вашу программу совместимой с текущей версией. Вы могли бы полностью удалить bindRedirect, это бессмысленно.