.NET中的引用如何定位? [英] How are references located in .NET?

查看:126
本文介绍了.NET中的引用如何定位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET在运行时用于定位引用程序集的过程是什么,它与编译期间用于定位引用程序集的过程不同吗?我对搜索的位置,搜索顺序以及可能影响结果的任何参数/配置设置特别感兴趣。

What process does .NET use to locate a referenced assembly at runtime and is it different than the process used to locate a referenced assembly during compilation? I am specifically interested in the locations that are searched and their search order and any parameters/configuration settings that might affect the outcome.

推荐答案

.NET应用程序中可以进行三种类型的引用。该答案仅涵盖下面列表中的前两个。

There are three types of references that can be made in a .NET application. This answer will only cover the first two in the list below.


  1. 文件引用。

  2. 项目引用

  3. 服务引用。

每个引用都必须解析。引用解析是以文件形式定位引用的具体实例的过程。解决项目引用的方式与解决文件引用的方式相同。项目引用仅允许您引用尚不存在的程序集(因为它是生成过程的输出。)

Every reference must be resolved. Reference resolution is the process of locating a concrete instance of a reference in the form of a file. Project references are resolved in the same way that file references are resolved. A project reference just allows you to reference assemblies that do not yet exist (because it is an output of the build process.)

重要的是要了解会发生引用解析在编译时和运行时,两者的过程完全不同。不了解这一点会导致无休止的头痛。相信我,我知道。

It is important to understand that reference resolution occurs at both compile time and at runtime and the process for each is totally different. Failing to understand this point can lead to endless headache. Believe me, I know.

运行时参考分辨率(又名绑定)

调用应用程序时,必须将其加载到内存中。如果应用程序在另一个程序集中使用对象,则该程序集也必须加载到内存中。 .NET框架使用以下过程来执行此操作。

When an application in invoked, it must be loaded into memory. If an application uses objects in another assembly, that assembly must also be loaded into memory. The .NET framework uses the following process to do this.


  1. 确定引用程序集的版本。


    • 在编译时将引用程序集的版本写入应用程序清单。除非在配置中被覆盖,否则将使用此版本。


      • application / web.config

      • 发布策略(覆盖application / web.config)

      • machine.config(覆盖发布策略和application / web.config)


  • 如果指定了代码库元素,则使用。


    • 如果未找到绑定失败。

    • 如果版本,文化或公钥不匹配,则绑定失败。


    • 如果未提供区域性,则搜索根目录/ [程序集名称]

    • 如果提供了区域性,则搜索根目录/ [文化]然后是根目录/ [文化] / [程序集名称]。

    • 如果web / app.config指定了探测元素,则在privatePath中搜索路径。路径必须相对于应用程序根目录。

    有关更多信息,请参见 http: //msdn.microsoft.com/zh-cn/library/yx7xezcf%28v=vs.110%29.aspx

    For more information see http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=vs.110%29.aspx.

    编译时间参考分辨率

    在构建过程中,MSBuild中发生了编译时分辨率。 MSBuild是Visual Studio和TFS都使用的生成引擎。请注意,对于ASP.NET应用程序,动态组件(aspx,asc,asax,cshtml等)在首次访问时会发生一个额外的编译步骤。这两种情况的参考解析如下所述。

    Compile time resolution occurs in MSBuild during the build process. MSBuild is the build engine used by both Visual Studio and TFS. Note that for ASP.NET applications, there is an extra compile step that occurs for dynamic components (aspx, asc, asax, cshtml, etc) when they are first accessed. Reference resolution for these two scenarios is described below.

    MSBuild

    在ResolveAssemblyReferences MSBuild目标中发生了组装分辨率。该目标调用ResolveAssemblyReference任务,将AssemblySearchPaths的值传递给SearchPaths参数,该参数的值分配如下。

    Assembly resolution occurs in the ResolveAssemblyReferences MSBuild target. This target invokes the ResolveAssemblyReference task passing the value of the AssemblySearchPaths to the SearchPaths parameter which is assigned a value as follows.

    <PropertyGroup>
            <!--
            The SearchPaths property is set to find assemblies in the following order:
    
                (1) Files from current project - indicated by {CandidateAssemblyFiles}
                (2) $(ReferencePath) - the reference path property, which comes from the .USER file.
                (3) The hintpath from the referenced item itself, indicated by {HintPathFromItem}.
                (4) The directory of MSBuild's "target" runtime from GetFrameworkPath.
                    The "target" runtime folder is the folder of the runtime that MSBuild is a part of.
                (5) Registered assembly folders, indicated by {Registry:*,*,*}
                (6) Legacy registered assembly folders, indicated by {AssemblyFolders}
                (7) Resolve to the GAC.
                (8) Treat the reference's Include as if it were a real file name.
                (9) Look in the application's output folder (like bin\debug)
            -->
        <AssemblySearchPaths Condition=" '$(AssemblySearchPaths)' == ''">
          {CandidateAssemblyFiles};
          $(ReferencePath);
          {HintPathFromItem};
          {TargetFrameworkDirectory};
          {Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
          {AssemblyFolders};
          {GAC};
          {RawFileName};
          $(OutDir)
        </AssemblySearchPaths>
    

    这里发生了很多事情,我并没有声称理解全部,但是我将尝试指出重要部分。

    There is a lot going on here and I don't claim to understand all of it, but I will try to point out the important parts.


    1. 查找参考的最常见位置是(按搜索顺序)


      • 手动添加到项目中的文件(例如/lib/coollib.dll>

      • 由提示路径指定的位置。

      • GAC

      • 应用程序输出路径。

    1. The most common locations to find a reference are (in search order)
      • Files added manually to project (ex. /lib/coollib.dll>
      • Location specified by hint path.
      • GAC
      • Application output path.

    ASP.NET Runtime Compiler

    除非以前在构建时使用pre-compile选项将其编译到项目输出文件夹中,否则所有动态内容(aspx,asc, asax,cshtml等)在首次访问应用程序时在运行时编译一次。此动态内容还可以依赖于其他程序集。 system.web>编译>程序集元素用于告知ASP.NET运行时编译器有关这些依赖项的信息,以便它可以引用它们。

    Unless previously compiled into the project output folder using the pre-compile option at build time, all dynamic content (aspx, asc, asax, cshtml, etc.) is compiled once at runtime when the application is first accessed. This dynamic content can also have dependencies on other assemblies. The system.web > compilation > assemblies element is used to tell the ASP.NET runtime compiler about these dependencies so that it can reference them.

    ASP.NET运行时编译器将在以下位置搜索这些引用。

    The ASP.NET runtime compiler will search the following locations in order for these references.


    1. 应用程序专用程序集缓存(也称为PAC),即/ bin文件夹。

    2. GAC (如果引用是使用强名称指定的。)

    请注意,默认情况下,根web.config引用了一些系统程序集和所有PAC中使用通配符语法的程序集。这意味着几乎不需要您手动将引用显式添加到system.web>编译>程序集元素。在许多情况下,您可以并且应该完全删除该元素。它仅应包含对存储在GAC中的程序集的引用。建议使用Copy Local = true来包括ASP.NET Runtime Compiler所需的非GAC引用。

    Note that by default, the root web.config references a few system assemblies and all assemblies in the PAC using the wildcard syntax. This means that you will rarely ever be required to explicitly add references manually to the system.web > compilation > assemblies element. In many cases you can and should delete the element entirely. It should only contain references to assemblies stored in the GAC. Using Copy Local = true is the recommended approach to include non-GAC references required by the ASP.NET Runtime Compiler.

    还请注意,如果使用system.web>编译>程序集元素,以使用程序集的强名称指定特定的版本号。 ASP.NET运行时编译器将尝试使用您指定的 exact 版本进行编译。如果在MSBuild编译阶段针对不同版本的程序集编译了应用程序的非动态组件,则可能导致问题。这是常见的情况,因为MSBuild将使用它可以找到的最新版本,并且如果您将特定版本设置为true,则只会使用确切的版本。

    Also note that many subtle errors can occur if you use the system.web > compilation > assemblies element to specify a specific version number using the assembly's strong name. The ASP.NET runtime compiler will attempt to compile using the exact version you specify. This can cause problems if the non-dynamic components of the application were compiled against a different version of the assembly during the MSBuild compilation phase. This is often the case because MSBuild will use the latest version it can find and only the exact version if you set specific version = true.

    其他资源:

    http://jack.ukleja.com/diagnosing-asp-net-page-compilation-errors/
    > http://blog.fredrikhaglund.se/blog/2008/02/23/get-control-over-your- assembly-dependencies /
    https: //dhakshinamoorthy.wordpress.com/2011/10/01/msbuild-assembly-resolve-order/
    http://www.beefycode.com/post/resolving-binary-references-in-msbuild.aspx

    这篇关于.NET中的引用如何定位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆