У меня есть две сборки: HelloWorld.exe и Hello.dll.Exe является основной сборкой, а dll используется основной сборкой.
Я скомпилировал как HelloWorld.exe (1.0.0), так и Hello.dll (1.0.0).Я поместил сборки в другую папку.
Затем я изменил версию Hello.dll на 2.0.0 и переписал Hello.dll 1.0.0 версией 2.0.0.Затем я запускаю HelloWorld.exe, и он работает нормально.
Я ожидал, что он сразу аварийно завершит работу, потому что ссылка Hello.dll, когда я компилировал EXE-файл, была 1.0.0.Теперь библиотека 1.0.0 была заменена на 2.0.0, но она все еще работает!
Согласно MSDN :
По умолчанию сборка будетиспользуйте только типы из той же сборки (имя и номер версии), с которой она была собрана и протестирована.То есть, если у вас есть сборка, которая использует тип из версии 1.0.0.2 другой сборки, она (по умолчанию) не будет использовать тот же тип из версии 1.0.0.4 другой сборки.Такое использование имени и версии для идентификации ссылочных сборок помогает избежать проблемы «DLL-ада» при обновлении до одного приложения, которое нарушает работу других приложений.
Вопросы:
- Почемуэто работает?
- Как заставить его НЕ работать?
- БОНУСНЫЙ ВОПРОС: Что происходит во время процесса сборки?Разве версия внешних зависимостей не жестко закодирована в основную зависимость?
Обратите внимание, что Hello.dll не имеет строгого имени.
Вот манифест дляHelloWorld.exe:
// Metadata version: v2.0.50727
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 2:0:0:0
}
.assembly extern Hello
{
.ver 2:0:0:0
}
.assembly HelloWorld
{
...//snipped
}
Вот журнал привязки сборки, взятый из Fuslogvw.exe (Средство просмотра журнала привязки сборки):
=== Pre-bind state information ===
LOG: User = ian.uy
LOG: DisplayName = Hello, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Users/ian.uy/Desktop/HelloWorld/HelloWorld/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/ian.uy/Desktop/HelloWorld/HelloWorld/bin/Debug/Hello.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Users\ian.uy\Desktop\HelloWorld\HelloWorld\bin\Debug\Hello.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: Hello, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
LOG: Binding succeeds. Returns assembly from C:\Users\ian.uy\Desktop\HelloWorld\HelloWorld\bin\Debug\Hello.dll.
LOG: Assembly is loaded in default load context.