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

时间:2014-06-03 18:14:18

标签: .net visual-studio

今天,我仔细研究了Visual Studio 2010中程序集引用的“特定版本”属性。经过一些意外结果的实验​​后,我开始尽可能多地了解该属性的工作原理。即便如此,在我看来,并没有得到所有的答案,所以这是我尝试自我回答这个问题:

完全如何在Visual Studio中使用程序集引用的“特定版本”属性?

2 个答案:

答案 0 :(得分:216)

它是一个编译时属性!

最重要的事情之一是"具体版本"是一个在运行时编译时生效的属性。

这是什么?

构建项目时,需要解析项目的程序集引用,以便找到构建系统应使用的物理程序集。如果"具体版本"执行检查(参见"何时是"特定版本"选中?"),它会影响装配解决过程的结果:

  • 构建系统找到可能使用的物理程序集
  • 构建系统将物理程序集的版本与存储在.csproj文件中的程序集版本进行比较以获取程序集引用
  • 如果两个程序集版本完全相同,则解析过程成功,找到的物理程序集用于构建
  • 如果两个装配版本不匹配,则会丢弃物理装配,并通过查找下一个可能的装配继续解析过程
  • 如果无法找到更多潜在的物理组件,则解析过程将失败。这会导致编译器警告(警告MSB3245),告诉您无法解析引用。
  • 有趣的是,构建然后继续!如果代码没有对程序集的实际引用,则构建成功(使用前面提到的警告)。如果代码具有引用,则构建将失败,并显示错误,该错误看起来好像代码使用的是未知类型或命名空间。构建真正失败的唯一迹象是警告MSB3245。

解决装配的顺序

程序集解析过程查找潜在程序集的顺序如下:

  1. .csproj文件中<HintPath>元素引用的程序集
  2. 项目输出路径
  3. GAC
  4. 请注意,如果GAC中存在多个版本的程序集,则解析过程首先尝试解析为具有最高版本的程序集。这只有在&#34;特定版本&#34;检查没有。

    何时是&#34;具体版本&#34;检查?

    Visual Studio决定是否执行&#34;特定版本&#34;检查.csproj文件中的两条信息:

    • <SpecificVersion>元素的存在与否及其值(如果存在)
    • 程序集参考中是否存在版本信息

    这是带有版本信息的典型程序集引用的样子:

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

    这就是程序集引用看起来像没有版本信息的方式:

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

    下表显示&#34;具体版本&#34;执行检查,不执行检查。

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

    令人惊讶的是,如果<SpecificVersion>和版本信息都不存在,则不会执行检查(案例6)。我本来希望执行检查并始终失败(与案例2相同),因为在我的理解中,<SpecificVersion>的缺席意味着默认值&#34; True&#34;。这可能是Visual Studio 2010的一个怪癖,我在那里进行了测试。

    在Visual Studio UI中检查程序集引用的属性(选择引用并按F4)时,您会看到&#34;特定版本&#34;的值。属性告诉您Visual Studio是否要执行&#34;特定版本&#34;校验。在案例6中,UI将显示&#34; True&#34;,尽管.csproj文件中不存在<SpecificVersion>元素。

    副作用&#34;复制本地&#34;

    如果&#34;复制本地&#34;属性设置为&#34; True&#34;但由于&#34;具体版本&#34;装配解决过程失败检查,没有复制装配。

    参考资料

答案 1 :(得分:32)

添加引用时,Visual Studio会在项目文件中记录程序集的[AssemblyVersion]。这个很重要。例如,如果您在一年后创建了一个错误修复程序,那么您需要确保使用完全相同版本的引用来重建项目,这样才能真正实现这一目标。如果引用程序集已更改,您将收到错误。

但这并不总是令人满意的。一些程序员让程序集版本自动递增,每次重建时都会生成一个新版本。尽管程序集的公共接口从未改变过。有些人通过使用Nuget来获取库来配置他们的项目,并在有新版本可用时让它自动更新库。他们希望将Specific Version属性设置为False以抑制编译错误。

了解后果非常重要,您需要重新部署整个程序版本以避免事故。运行时版本不匹配导致程序崩溃,并且只能在.config文件中使用<bindingRedirect>进行抑制,这是有风险的。