简体   繁体   English

程序集引用的“特定版本”属性在Visual Studio中的工作原理是什么?

[英]How exactly does the “Specific Version” property of an assembly reference work in Visual Studio?

Today I had a closer look at the "Specific Version" property of assembly references in Visual Studio 2010. After a few experiments with unexpected results I set out to learn as much as possible about how the property works. 今天,我仔细研究了Visual Studio 2010中程序集引用的“特定版本”属性。经过一些意外结果的实验​​后,我开始尽可能多地了解该属性的工作原理。 Even SO, it appears to me, does not have all the answers, so here is my attempt at self-answering the question: 即便如此,在我看来,并没有得到所有的答案,所以这是我尝试自我回答这个问题:

How exactly does the "Specific Version" property of an assembly reference work in Visual Studio? 究竟怎样在Visual Studio程序集引用作品的“特定版本”属性?

It's a compile-time property! 这是一个编译时的属性!

One of the most important things to know is that "Specific Version" is a property that takes effect at compile-time and not at runtime. 要知道的最重要的事情之一是“特定版本”是一个在编译时而 不是在运行时生效的属性。

What is it all about? 这是什么一回事呢?

When a project is built, the project's assembly references need to be resolved in order to find the physical assemblies that the build system should use. 构建项目时,需要解析项目的程序集引用,以便查找构建系统应使用的物理程序集。 If the "Specific Version" check is performed (see section "When is "Specific Version" checked?"), it affects the outcome of the assembly resolution process: 如果执行“特定版本”检查(请参阅“何时”特定版本“选中?”部分),则会影响装配解决过程的结果:

  • The build system locates a physical assembly that it can potentially use 构建系统定位它可能使用的物理程序集
  • The build system compares the physical assembly's version to the assembly version stored in the .csproj file for the assembly reference 构建系统将物理程序集的版本与存储在.csproj文件中的程序集版本进行比较,以获得程序集引用
  • If the two assembly versions are exactly the same, the resolution process succeeds and the physical assembly found is used for the build 如果两个程序集版本完全相同,则解析过程成功,找到的物理程序集用于构建
  • If the two assembly versions do not match, the physical assembly is discarded and the resolution process continues by locating the next potential assembly 如果两个组件版本不匹配,则丢弃物理组件,并通过定位下一个可能的组件继续解析过程
  • If no more potential physical assemblies can be located, the resolution process fails. 如果无法找到更多可能的物理组件,则解析过程将失败。 This results in a compiler warning (warning MSB3245) that tells you that the reference could not be resolved. 这会导致编译器警告(警告MSB3245),告诉您无法解析引用。
  • Interestingly enough, the build then continues! 有趣的是, 构建然后继续! If the code has no actual references to the assembly, the build succeeds (with the previously mentioned warning). 如果代码没有对程序集的实际引用,则构建成功(使用前面提到的警告)。 If the code has references, the build fails with an error that looks as if the code were using unknown types or namespaces. 如果代码具有引用,则构建将失败,并显示错误,该错误看起来好像代码使用的是未知类型或命名空间。 The only indication why the build really failed is the warning MSB3245. 构建真正失败的唯一迹象是警告MSB3245。

Order in which assemblies are resolved 解决装配的顺序

The order in which the assembly resolution process locates potential assemblies appears to be this: 程序集解析过程查找潜在程序集的顺序如下所示:

  1. The assembly referenced by the <HintPath> element in the .csproj file 由.csproj文件中的<HintPath>元素引用的程序集
  2. The project output path 项目输出路径
  3. The GAC GAC

Note that if several versions of the assembly exist in the GAC, the resolution process first attempts to resolve to the assembly with the highest version. 请注意,如果GAC中存在多个版本的程序集,则解析过程首先尝试解析为具有最高版本的程序集。 This is important only if the "Specific Version" check is not made. 仅在未进行“特定版本”检查时,这一点很重要。

When is "Specific Version" checked? 何时检查“特定版本”?

Visual Studio bases its decision whether to perform the "Specific Version" check on two pieces of information found in the .csproj file: Visual Studio决定是否对.csproj文件中的两条信息执行“特定版本”检查:

  • The presence or absence of the <SpecificVersion> element, and its value (if it is present) 是否存在<SpecificVersion>元素及其值(如果存在)
  • The presence or absence of version information in the assembly reference 程序集引用中是否存在版本信息

This is how a typical assembly reference with version information looks like: 这是带有版本信息的典型程序集引用的样子:

<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>True</SpecificVersion>
  <HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>

And this is how the assembly reference looks like without version information: 这就是没有版本信息时程序集引用的样子:

<Reference Include="Foo">
[...]

The following table shows when the "Specific Version" check is performed, and when it is not. 下表显示执行“特定版本”检查的时间,以及何时不执行。

                            |     Version information
                            |  Present       Not present
----------------------------+------------------------------
<SpecificVersion>           |
- Present, has value True   |    Yes (1)        Yes (check always fails) (2)
- Present, has value False  |    No  (3)        No (4)
- Not present               |    Yes (5)        No (6)

The surprising thing here is that no check is performed if both <SpecificVersion> and version information are absent (case 6). 令人惊讶的是,如果不存在<SpecificVersion>和版本信息,则不执行检查(案例6)。 I would have expected the check to be performed and to always fail (same as case 2) because in my understanding the absence of <SpecificVersion> implies the default value "True". 我本来希望执行检查并始终失败(与案例2相同),因为在我的理解中,缺少<SpecificVersion>意味着默认值“True”。 This may be a quirk of Visual Studio 2010 where I did my tests. 这可能是Visual Studio 2010的一个怪癖,我在那里进行了测试。

When you examine the properties of an assembly reference in the Visual Studio UI (select the reference and hit F4), the value you see for the "Specific Version" property tells you whether or not Visual Studio is going to perform the "Specific Version" check. 在Visual Studio UI中检查程序集引用的属性(选择引用并按F4)时,您在“特定版本”属性中看到的值会告诉您Visual Studio是否要执行“特定版本”校验。 In case 6 the UI will show "True", although the <SpecificVersion> element is not present in the .csproj file. 在案例6中,UI将显示“True”,尽管.csproj文件中不存在<SpecificVersion>元素。

Side-effects on "Copy local" 对“复制本地”的副作用

If the "Copy Local" property is set to "True" but the assembly resolution process fails because of the "Specific Version" check, no assembly is copied. 如果“复制本地”属性设置为“True”但由于“特定版本”检查而导致程序集解析过程失败,则不会复制任何程序集。

Reference material 参考资料

When you add a reference then Visual Studio records the [AssemblyVersion] of the assembly in the project file. 添加引用时,Visual Studio会在项目文件中记录程序集的[AssemblyVersion]。 This is important. 这个很重要。 If you, say, create a bug fix a year later then you want to make sure that you rebuild the project with the exact same version of the reference so it is a true drop-in. 例如,如果您在一年后创建了一个错误修复程序,那么您需要确保使用完全相同的引用版本重新构建项目,这样才能真正实现这一目标。 You'll get an error if the reference assembly has changed. 如果引用程序集已更改,您将收到错误。

But that isn't always desirable. 但这并不总是令人满意的。 Some programmers let the assembly version automatically increment, generating a new version every single time they rebuild. 一些程序员让程序集版本自动递增,每次重建时都会生成一个新版本。 Even though the public interface of the assembly never changed. 尽管程序集的公共接口从未改变过。 Some configure their project by using Nuget to obtain libraries and let it automatically update the library when there's a new release available. 有些人通过使用Nuget获取库来配置他们的项目,并在有新版本可用时让它自动更新库。 They will like to set the Specific Version property to False to suppress the compile error. 他们希望将Specific Version属性设置为False以抑制编译错误。

Pretty important to understand the consequence, you do need to redeploy the entire build of the program to avoid accidents. 了解后果非常重要,您需要重新部署整个程序版本以避免事故。 Version mismatches at runtime crash the program and can only be suppressed with a <bindingRedirect> in the .config file which is risky. 运行时版本不匹配会导致程序崩溃,并且只能通过.config文件中的<bindingRedirect>来抑制这种风险。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 解决程序集冲突问题-Visual Studio项目参考+特定版本 - solving an assembly conflict issue — Visual Studio project reference + specific version 为什么Visual Studio 2012引用了错误版本的程序集? - Why does Visual Studio 2012 reference the wrong version of an assembly? 在Visual Studio 2008中使用特定版本引用 - Use of specific version reference in Visual Studio 2008 如何使用 Visual Studio 2017 创建参考程序集 - How to create a Reference Assembly with Visual Studio 2017 如何在没有 Visual Studio 的情况下引用程序集(* .dll)? - How to reference an assembly(*.dll) without visual studio? 如何在Visual Studio中抑制程序集引用警告? - How to suppress assembly reference warnings in Visual Studio? 如何使用NAnt引用在Visual Studio中生成的程序集(并使我的应用程序正常工作)? - How can I reference an assembly generated in Visual Studio with NAnt (and make my app work)? 构建项目时,“复制本地”在 Visual Studio 中究竟是如何工作的 - How exactly does "Copy Local" work in Visual Studio while building the project 在运行时不是特定于版本的Visual Studio项目参考 - Visual Studio project reference that isn't version specific at runtime 在Visual Studio 2012中生成XML序列化程序集不起作用 - Generating XML Serialization Assembly in Visual Studio 2012 does not work
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM