(.NET) Как мне работать с двумя версиями одного и того же типа при создании плагина?

Мы создаем плагин для коммерческого приложения, использующего последнюю версию коммерческого UI-фреймворка. Наш плагин ссылается на другую (старую) версию той же платформы, а также на DLL-файлы API для приложения, к которому он подключается. Теперь мы получаем конфликт повторяющегося типа (CS0433) во время выполнения при загрузке определенных частей коммерческого приложения.

Это (более или менее) ситуация:

http://img39.imageshack.us/img39/769/conflictingreferences.jpg

Кто-нибудь знает, как это решить?


person Mike Burton    schedule 28.05.2009    source источник


Ответы (5)


Откуда взялся общий пользовательский интерфейс и насколько сложно его обновить?

Мне кажется, это лучший подход.

person ChrisF    schedule 28.05.2009
comment
Это примерно полмиллиона строк сложного кода (технически несложный, просто Большой шар грязи) и небольшая команда, у которой есть еще 10 вещей на нашей тарелке в любой момент времени, а также бесконечный стек прямой поддержки. Между нами и версией, которую использует другое приложение, существует 5 версий фреймворка. Кроме того, я действительно не хочу связывать нас с другой версией этого фреймворка, если мне это не нужно. - person Mike Burton; 29.05.2009
comment
А, вы исследовали ссылки на определенные версии фреймворка? Не уверен, возможно ли это, учитывая вашу настройку. - person ChrisF; 29.05.2009
comment
К сожалению, проблема не в нашем коде - приложение пытается загрузить свою копию фреймворка и сталкивается с конфликтом типов. - person Mike Burton; 01.06.2009
comment
В итоге мы выбрали эту стратегию. Я рассматривал возможность загрузки всего плагина в отдельный домен приложений через мост, но мы решили, что это будет значительно труднее и более подвержено поломкам в будущем. Мне это не нравится, но, полагаю, Вселенную не особо беспокоит, что мне нравится в этом случае. - person Mike Burton; 05.06.2009

Я не думаю, что .NET Framework (по крайней мере до 3.5) действительно может загружать две разные версии одной сборки в приложение. Я полагаю, что где-то читал, что 4.0 может иметь некоторые дополнительные возможности в этой области, но я не обязательно на это рассчитываю.

Единственный способ, которым это может работать, - это если приложение, загружающее плагины, загружает их в отдельные домены приложений, но я предполагаю, что у вас нет контроля над приложением загрузки.

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

person jerryjvl    schedule 29.05.2009
comment
В качестве дополнения для отдельного плагина, в котором я могу больше контролировать схему загрузки, мы используем подход AppDomain. Его непросто настроить, но я думаю, что стоит день или два, чтобы все заработало должным образом. - person Mike Burton; 17.06.2009

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

В MSDN есть информация по этому поводу.

person Lucero    schedule 28.05.2009
comment
Однако мы не говорим о разнице в одной или двух версиях. Здесь вызывает беспокойство то, что более новая версия почти наверняка частично или полностью несовместима с версией, которую мы используем в настоящее время, и нарушила бы наш код пользовательского интерфейса (возможно, труднодоступными способами). - person Mike Burton; 29.05.2009
comment
Один из способов справиться с этим - оставить старые вызовы API с пометкой [Obsolete] (вы можете сделать так, чтобы атрибут Obsolete выдавал ошибку при компиляции, чтобы новый код не мог быть скомпилирован с использованием устаревших методов). - person Lucero; 29.05.2009

Я ответил на это здесь Ошибка компиляции CS0433 на предварительно скомпилированном сайте ASP.NET 2.0

вы можете использовать ключевые слова extern и alias в своем коде и указать новый (отличный от глобального по умолчанию) псевдоним при ссылке на сборку.

extern alias global2;
using global2::System;
person RandomNickName42    schedule 31.05.2009
comment
Это работает для ошибок компиляции, но не для ошибок времени выполнения. Я уже пытался использовать псевдонимы, но они не решают проблему. - person Mike Burton; 01.06.2009

Правильно, меня сбило с толку, что вы искали динамическую информацию из заголовка, как говорится, «здание».

Вы пробовали эту настройку app.config?

<configuration> Element
  <runtime> Element
    <assemblyBinding> Element for <runtime>
      <qualifyAssembly> Element

<qualifyAssembly partialName="PartialAssemblyName"
                                  fullName="FullAssemblyName"/>

Как насчет этого?

<configuration>
   <runtime>
      <assemblyBinding>
         <dependentAssembly>
<bindingRedirect  
   oldVersion="old assembly version"
   newVersion="new assembly version"/>

Предполагая, что вы уже пробовали Assembly :: Load, замену Assembly.LoadWithPartialName, оба должны позволить вам загружаться без указания какой-либо информации о версии.

Вы прочитали Дэйва Граймса семинар для слияния? В нем подробно рассказывается о том, как управлять системами разрешения типов в среде CLR. У него также есть хорошая безопасность и инструментальная мастерская .net.

person RandomNickName42    schedule 01.06.2009
comment
Я забыл сказать, что вам может потребоваться более конкретная информация об этой архитектуре, чтобы действительно ответить лучше, чем те из нас, кто до сих пор делал это, действительно неоднозначно относительно того, какой слой вы используете, что оставляет довольно много открытых сделал я? ... - person RandomNickName42; 02.06.2009