Использование разных версий одной сборки в одной папке

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

Проект A

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

Проект B

 - Uses NHibernate
 - Uses Castle Windsor v2.1

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

4 ответов


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

<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>

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

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

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

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


одним из решений (или обходным путем) было бы установить обе версии в Глобальный Кэш Сборок (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 отметить все типы из второй сборки (Замок в этом случае) internal в выходной сборке. Без этого вы можете получить ошибки компиляции при попытке скомпилировать проект, ссылающийся на оба ваших новых NHibernate.dll и версия полки Castle.DynamicProxy2.dll v2.2, поскольку они будут содержать классы с точно такими же именами.


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

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