Ссылка на разные версии одной и той же сборки - PullRequest
33 голосов
/ 21 октября 2008

Если A ссылается на сборку B 1.1 и C, а C ссылается на B 1.2, как избежать конфликтов сборки?

Я предполагал, что ссылки C будут инкапсулированы и не вызовут никаких проблем, но, похоже, все dll скопированы в корзину, где и возникает проблема.

Я понимаю, что существует два способа использования GAC или привязок сборки? GAC не кажется мне лучшим подходом, так как мне не нравится предполагать, что dll будет там, я предпочитаю ссылаться на dll из каталога lib в моем решении.

Если привязки к сборке не кажутся мне надежными, что, если одна версия сборки имеет функциональность, которой нет у другой, не вызовет ли это проблем?


В моем случае это потому, что я использую стороннюю библиотеку dll, использующую более старую версию nHibernate, чем я сам.

Ответы [ 5 ]

9 голосов
/ 21 октября 2008

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

Кроме того, вы уже прочитали это еще?

7 голосов
/ 24 августа 2011

На первый взгляд малоизвестный способ сделать это - использовать ключевое слово extern.

Из C # Ссылка

Чтобы сослаться на две сборки с одинаковыми полными именами типов, псевдоним должен быть указан в командной строке следующим образом:

/ г: GridV1 = grid.dll

/ г: GridV2 = grid20.dll

Это создает внешние псевдонимы GridV1 и GridV2. Чтобы использовать эти псевдонимы из программы, ссылки на них с помощью extern ключевое слово. Например:

внешний псевдоним GridV1;

внешний псевдоним GridV2;

В каждом объявлении внешнего псевдонима вводится дополнительный корневой уровень пространство имен, которое параллельно (но не лежит внутри) глобальное Пространство имен. Таким образом, типы из каждой сборки можно ссылаться без двусмысленность, используя их полностью определенное имя, коренящееся в соответствующий псевдоним пространства имен.

В предыдущем примере GridV1 :: Grid будет элементом управления сеткой из grid.dll и GridV2 :: Grid будет элементом управления сеткой из grid20.dll.

3 голосов
/ 01 августа 2013

Мне потребовалось поддерживать несколько версий сборки, и я нашел это решение:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="MyAssembly" publicKeyToken="..." />
        <codeBase version="1.1.0.0" href="MyAssembly_v1.1.0.0.dll"/>
        <codeBase version="2.0.0.0" href="MyAssembly_v2.0.0.0.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
1 голос
/ 22 октября 2008

.NET Runtime прекрасно подходит для загрузки нескольких версий одной и той же сборки одновременно. Однако если вы собираетесь открыть эту банку с червями, я настоятельно рекомендую вам строго назвать свои сборки и использовать схему именования Major.Minor. *, Чтобы избежать конфликтов имен.

Я не думаю, что вы должны думать о едином подходе к использованию GAC (или нет). GAC может быть очень полезен, если вы хотите автоматически использовать новые функциональные возможности, опубликованные в будущих версиях DLL. Конечно, это благословение стоит того, что новые версии могут работать не совсем так, как вы ожидаете их тоже :). Все зависит от того, что наиболее практично, и насколько вы контролируете то, что публикуется в GAC.

С уважением, -Alan.

1 голос
/ 21 октября 2008

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

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>
...