Использование разных версий одной и той же сборки в одной папке - PullRequest
61 голосов
/ 17 марта 2010

У меня следующая ситуация

Проект A

 - Uses Castle Windsor v2.2
 - Uses Project B via WindsorContainer

Проект B

 - Uses NHibernate
 - Uses Castle Windsor v2.1

В папке bin проекта A у меня есть dll Castle.DynamicProxy2.dll v2.2 и NHibernate dll. Теперь проблема в том, что NHibernate зависит от Castle.DynamicProxy2.dll v2.1, которого там нет. Как мне разрешить эту ситуацию?

Ответы [ 4 ]

90 голосов
/ 17 марта 2010

Я использовал следующую конфигурацию для решения проблемы.

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Castle.DynamicProxy2" publicKeyToken="407dd0808d44fbdc" />
                <codeBase version="2.1.0.0" href="v2.1\Castle.DynamicProxy2.dll" />
                <codeBase version="2.2.0.0" href="v2.2\Castle.DynamicProxy2.dll" />
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" />
                <codeBase version="1.1.0.0" href="v2.1\Castle.Core.dll" />
                <codeBase version="1.2.0.0" href="v2.2\Castle.Core.dll" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>
9 голосов
/ 20 сентября 2013

Одна вещь очень, очень, очень важная, которую можно пропустить, если он не уделяет достаточно внимания.

Сборка, которую вы пишете в теге версии codeBase, должна иметь строгое имя.

По следующей ссылке: http://msdn.microsoft.com/en-us/library/efs781xb.aspx

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

9 голосов
/ 17 марта 2010

Одним из решений (или обходного пути) было бы установить обе версии в Global Assembly Cache (GAC) на компьютерах, на которых должно работать ваше программное обеспечение, и ссылаться на сборки, используя их надежные имена. Это предполагает, что сборки действительно имеют строгие имена.

Установка в GAC будет проблематичной, если у вас более нескольких разработчиков или вы планируете развернуть свое решение на многих компьютерах (например, в качестве приложения для конечного пользователя). В этом случае я считаю (но я могу ошибаться), что ваш единственный вариант - объединить одну из двух версий в сборку, требующую эту версию. В вашем конкретном случае вам необходимо объединить Castle.DynamicProxy2.dll v2.1 с NHibernate.dll.

Вы можете использовать инструмент под названием ILMerge для объединения сборок. Команда, которую вам нужно будет выполнить, выглядит примерно так (не проверено):

ILMerge /t:library /internalize /out:Deploy/NHibernate.dll
    NHibernate.dll Castle.DynamicProxy2.dll

Переключатель /internalize указывает ILMerge пометить все типы из второй сборки (в данном случае Castle) internal в выходной сборке. Без этого вы можете получить ошибки компиляции, когда попытаетесь скомпилировать проект, ссылающийся как на новую NHibernate.dll, так и на полочную версию Castle.DynamicProxy2.dll v2.2, поскольку они будут содержать классы с точно такими же именами.

2 голосов
/ 18 октября 2010

Я не думаю, что решение Hemanshu Bhojak 'является хорошим, поскольку вы не хотите загружать две версии одной и той же сборки в один и тот же контекст. Эта статья объясняет, почему:

http://msdn.microsoft.com/en-us/library/dd153782.aspx#avoid_loading_multiple_versions

...