2012-07-04 2 views
9

Какова наилучшая практика в .NET-мире для управления транзитивными зависимостями, которые вызывают конфликт версий?Transitive Dependency вызывает противоречивую версию той же DLL

В деталях: Проект A зависит от проекта В, который, в свою очередь, зависит от библиотеки C

также

Проект А также зависит от проекта X, который зависит от различных и (потенциально) несовместимой версии библиотеки С.

A-> B-> Cv1.0
&
А-> Х-> Cv2.0
где
CV1 .0 <> Cv2.0

  • Есть ли способ сделать эту работу?

  • Можно ли это сделать БЕЗ использования GAC?

  • Можно ли это сделать, даже если B и X только в двоичном формате (источник недоступен)?

Другими словами, существует способ, когда я могу иметь проекты B и X, каждый из которых использует свои собственные зависимости при совместном использовании в проекте A, не вызывая конфликтов.

ПРИМЕЧАНИЕ. Я понимаю, что в идеале я не должен иметь этой проблемы вообще, но поскольку зависимость от внешних библиотек расширяется, это будет неизбежным побочным эффектом. Поэтому я задаюсь вопросом, должно ли это происходить, как лучше всего справиться с этим.

+1

В идеале вы должны перестроить или обновить B так, чтобы он зависел от текущей версии C. Если вы не можете этого сделать, вы можете попробовать перепрограммировать версии. http://stackoverflow.com/a/11126867/48082 Это не гарантируется! – Cheeso

+1

Согласились, что в идеале нужно очистить свои проекты, чтобы избежать ситуации в уютном месте, но это не всегда возможно, следовательно, вопрос. – Newtopian

+0

переназначение DLL в некотором роде хорош только в том случае, если обе версии совместимы друг с другом. Худший сценарий здесь заключается в том, что в случае, если они несовместимы, есть способ, чтобы каждая средняя зависимость использовала версию, для которой она была создана, и по-прежнему выполняет работу, которую ожидает их основной проект. – Newtopian

ответ

4

Есть много подобных вопросов. Переполнение стека. . Referencing 2 different versions of log4net in the same solution

Резюме:

  1. Убедитесь, что при развертывании сборки C в папки 1.0 и 2.0 соответственно в папке, содержащей основной исполняемый файл.
  2. Изменение app.config файла и включают в себя что-то вроде следующего:
<configuration> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="C" publicKeyToken="C's public key token" /> 
     <codeBase version="version string for C1.0 e.g. 1.0.0.0" href="1.0\C.dll" /> 
     <codeBase version="version string for C2.0 e.g. 2.0.0.0" href="2.0\C.dll" /> 
     </assemblyIdentity> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
</configuration> 

вы можете получить открытый ключ маркер С помощью зп -Т C.dll

Если v1. 0 и v2.0 из C имеют разный открытый ключ (хотя в идеале они не должны), то включают два зависимых тега сборки.

+1

действительно есть много вопросов, но никто не ответил на мой вопрос. Мое понимание assemblyBinding заключалось в том, что он позволяет указать, какая DLL используется для какого пространства имен и соответственно перенаправлять вызовы. Здесь каждый путь вызова в конечном итоге нацелен на одну DLL. В описанном сценарии у нас есть два одинаковых пути вызова, которые должны ориентироваться на две разные DLL. Единственное различие заключается в том, что каждый из них вызывается из другой «родительской» DLL. То есть, если я не понял правильно цель assemblyBinding. – Newtopian

+0

Tha сказал, что я предполагаю, что если издатель двух зависимостей (B и X в приведенном выше примере) должен был специально очертить версии зависимостей DLL (C выше) при создании своих библиотек, все будет просто работать (при условии, что C Dll однозначно идентифицируется файлы, т.е. другое имя и/или пути). Мне нужно немного поэкспериментировать с assemblyBinding, см., Что можно сделать. – Newtopian

+0

Если C сильно пронумеровано, выше должно работать и должно быть в состоянии загрузить правильную версию C для B и X. Если она не сильно названа, но все еще имеет версию (как указано в атрибуте AssemblyVersion), вы можете поэкспериментировать с удалением publicKeyToken и посмотреть, все ли работает. Если это не сработает, я надеюсь, что только событие AssemblyResolve будет надежным. Я попытаюсь проверить все эти ifs и buts и поделиться результатами. –

Смежные вопросы