.NET 中的引用是如何定位的?

2023-11-24

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


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

  1. 文件参考。
  2. 项目参考
  3. 服务参考。

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

重要的是要理解引用解析发生在编译时和运行时,并且每个过程都完全不同。如果不理解这一点,就会导致无尽的头痛。相信我,我知道。

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

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

  1. Determine version of referenced assembly.
    • The version of the referenced assembly is written to the applications manifest at compile time. This version will be used unless overridden in configuration.
      • 应用程序/web.config
      • 发布策略(覆盖 application/web.config)
      • machine.config(覆盖发布策略和 application/web.config)
  2. 如果程序集之前已加载,则从缓存中重新使用。
  3. 如果提供了强名称,请搜索 GAC。
  4. Probe
    • If codebase element specified, then use.
      • 如果没有找到则绑定失败。
      • 如果版本、区域性或公钥不匹配,则绑定失败。
    • Search application base path. Matches by simple name and fails if first match is wrong version.
      • 如果未提供区域性,则搜索 root,然后搜索 root/[程序集名称]
      • 如果提供了区域性,则搜索 root/[culture],然后搜索 root/[culture]/[程序集名称]。
      • 如果 web/app.config 指定探测元素,则在 privatePath 中搜索路径。路径必须相对于应用程序根目录。

欲了解更多信息,请参阅http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=vs.110%29.aspx.

编译时参考分辨率

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

MSBuild

程序集解析发生在 ResolveAssemblyReferences MSBuild 目标中。此目标调用 ResolveAssemblyReference 任务,将 AssemblySearchPaths 的值传递给 SearchPaths 参数,该参数的值分配如下。

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

这里发生了很多事情,我并不声称理解了所有内容,但我会尽力指出重要的部分。

  1. The most common locations to find a reference are (in search order)
    • 手动添加到项目的文件(例如/lib/coollib.dll>
    • 由提示路径指定的位置。
    • GAC
    • 应用程序输出路径。
  2. 使用 Copy Local = true 标记的引用将复制到应用程序输出路径after汇编。这意味着此设置的值对 MSBuild 的参考解析过程没有影响。请注意,复制本地 UI 设置映射到<private>项目文件中的元素。
  3. MSBuild 将始终尝试使用给定程序集可用的最新版本,除非指定了特定版本 = true。此设置的默认值为 false,这意味着在搜索 GAC 时,无论项目定义中指定的版本如何,都将始终使用最新版本的 DLL。

ASP.NET 运行时编译器

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

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

  1. 应用程序私有程序集缓存(又名 PAC),即 /bin 文件夹。
  2. GAC(如果使用强名称指定引用)。

请注意,默认情况下,根 web.config 使用通配符语法引用一些系统程序集和 PAC 中的所有程序集。这意味着您很少需要手动显式添加对 system.web >compilation >assemblies 元素的引用。在许多情况下,您可以而且应该完全删除该元素。它应该只包含对存储在 GAC 中的程序集的引用。建议使用 Copy Local = true 方法来包含 ASP.NET 运行时编译器所需的非 GAC 引用。

另请注意,如果您使用 system.web >compilation >assemblies 元素通过程序集的强名称指定特定版本号,则可能会发生许多细微错误。 ASP.NET 运行时编译器将尝试使用exact您指定的版本。如果在 MSBuild 编译阶段针对不同版本的程序集编译应用程序的非动态组件,这可能会导致问题。这种情况经常发生,因为 MSBuild 将使用它可以找到的最新版本,并且如果您设置特定版本 = 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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET 中的引用是如何定位的? 的相关文章

  • AllowUserToAddRows 不适用于 DataGridView 上的 List<> 数据源

    我有一个DataGridView与DataSource set to List
  • 收集仍在范围内的对象 - GC.Collect

    我读过这篇文章 https devblogs microsoft com oldnewthing 20100810 00 p 13193 https devblogs microsoft com oldnewthing 20100810 0
  • 在 .NET 中解析 FIX 协议消息的最有效方法是什么?

    我碰到这个非常相似的问题 https stackoverflow com questions 2311205 the best way to parse a fix message但该问题被标记为 QuickFIX 与我的问题无关 并且大多
  • 并行何时会提高性能

    我试图理解何时使用parallel会提高性能 我用一个简单的代码对其进行了测试 该代码运行了超过 100 000 个项目List
  • 通过 Active Directory 搜索进行有效分页

    在 NET 中使用 Active Directory 搜索进行分页的有效方法是什么 在 AD 中进行搜索的方法有很多 但到目前为止我找不到如何有效地进行搜索 我希望能够表明Skip and Take参数并能够检索结果中与我的搜索条件匹配的记
  • 使用 C# 在 Windows 窗体应用程序中正确使用 OnClick 与 MouseClick 事件

    我目前正在开发一个自定义控件 并意识到我的代码正在运行两次 这实际上并不是一个大问题 它只是 Focus 方法调用 不过 我想了解一下 从阅读点击 MSDN说明单击事件 http msdn microsoft com en us libra
  • 如何从 nuget 包中排除子目录和内容

    所以我有一个网站正在尝试打包用于 Octopus Deploy 我有以下文件夹结构 Web Views WantThis Dontwantthis WantThis1 WantThis2 lots more Scripts 我试图排除 Do
  • 如何在类文件中使用BackGroundWorker?

    我的program cs调用mdi父frmMain frmMain 然后根据用户操作打开不同的子表单 所有的处理逻辑都写在BusinessLogic cs中 frmMain 在加载时调用 BusinessLogic cs 的方法来初始填充数
  • 当文件已存在时无法创建该文件

    我正在使用 Winforms 并且尝试将文件从一个位置复制到另一个位置 如果同名文件已经存在 我想覆盖它 但我收到类似 当文件已存在时无法创建文件 的错误 我想覆盖该文件 我应该怎么办 我试过File copy代替File move 但我遇
  • .NET Core 3 是否支持 TLS 1.3

    我正在使用 NET Core 3 0 制作仅支持 TLS 1 3 的代理 我看到 SslProtocols 中定义了 Tls13 12288 但在我的测试过程中 它只抛出异常 客户端和服务器无法通信 因为它们不具备通用算法 所以我的问题是
  • 如何在应用程序目录层次结构中构建接口?

    将它们全部放在一个单独的文件夹结构中还是与实现它们的类一起放置 切勿将接口与实现它们的类放在一起 除非这些类满足以下要求 这样做将引入一个紧耦合在接口和实现者之间 如果不同时引用实现者 您将无法创建该接口的其他实现 你基本上有两个选择 将接
  • .NET 的 C 代码解析器

    有谁知道 NET 的 C 解析器库吗 我打算将 C 代码解析为某种形式的对象图 这样我就可以将其转换为不同的语言 ANTLR 可以做你想做的事 它有一个 C 预处理器和 ANSI C 语法 https github com antlr gr
  • .net core 1.1 中嵌入的 power bi

    目前 我正在尝试在 Visual Studio 2017 中为我的 net core 1 1 项目导入 powerbi 包 但是 我收到以下错误 Install Package Package Microsoft PowerBI Core
  • 使用 Serilog 时如何在输出消息中获取丰富的属性

    我正在尝试使用 Serilog 将丰富的属性输出到渲染的消息中 private static Tester GetTester return new Tester Count 7 Name Redmond Log Logger new Lo
  • 如何获取 ASP.NET MVC 中当前的虚拟路径?

    如何从 ASP NET MVC 视图中获取当前路径 URL 如果没有办法将其获取到视图中 那么如何将其获取到控制器中以便将其传递到视图呢 EDIT 我不需要 url 的协议和主机部分 这将为您返回视图中的 url
  • 如何通过ConfigurationManager找到配置文件位置?

    如何通过ConfigurationManager找到配置文件位置 我在代码中有 ConfigurationManager 类 并且正在调试它 我想知道它指向哪个配置文件 web config 或 app config 等 Configura
  • 检测笔记本电脑盖子的关闭和打开

    是否可以检测笔记本电脑的盖子何时打开或关闭 从我读到的内容来看 这是不可能的 但 SO 之前已经帮助我完成了不可能的任务 我发现唯一可能朝着正确方向的事情是关于报告电源按钮所需的 IOCTL 的 MSDN 博客文章 https learn
  • 使用 apachesoap:使用 .net 在 Web 服务中映射复杂数据类型

    我有一个用 Coldfusion 编程的 Web 服务 我试图使用 c net 来使用它 特定的 Web 服务返回一个 Coldfusion 结构 具有键和值的项目的集合 该结构由 Web 服务公开为 apachesoap Map 类型的复
  • 如何获取运行或段落的高度

    我找到了Run or Paragraph in FlowDocument现在我需要知道HEIGHT of it i e while navigator CompareTo flowDocViewer Document ContentEnd
  • 有没有办法在 C# 中仅通过文件名查找文件?

    我们现在使用绝对路径或相对路径在 C 应用程序中查找文件 如果文件位于当前工作目录下或 路径 之一下 有没有办法仅通过名称查找文件 使用绝对路径不好 使用相对路径也不够好 因为我们可能通过重命名或移动项目文件夹来更改项目结构 如果我们的代码

随机推荐

  • 在 Apache 上使用 PHP 进行长轮询

    希望我能很好地解释这一点 我正在努力创建一个通过 PHP 处理 ajax 请求的 PHP 库以面向对象的方式 我目前正在考虑一种实现长轮询解决方案的好方法 但对某些事情感到好奇 Apache 不能很好地保持多个连接打开 每个请求一个线程的模
  • scipy中样条插值的系数

    我想通过 scipy 计算样条插值的系数 在 MATLAB 中 x 0 3 y 0 1 4 0 spl spline x y disp spl coefs 它会返回 ans 1 5000 5 5000 3 0000 0 1 5000 1 0
  • 在 Javascript contenteditable div 中插入文本

    有没有办法将文本 字符串 可能有也可能没有 html 标签 插入到div 它必须是一个div而不是一个textarea 首先 我需要获取光标位置 然后在该位置插入文本 和函数类似insertAdjacentText 但只能在标签之前或之后插
  • VS调试问题,谁能帮我解释一下?

    一段C 代码 var isTrue new List
  • 压缩字体以在网络中使用

    在用作网络字体之前可以对字体进行某种压缩吗 我有一个 150kB 的字体文件 能不能压缩一下 而且如果我要求两种字体 eot and ttf两者都会被浏览器下载吗 如果您使用 FontSquirrel font face 套件生成器 htt
  • WSO2 ESB DBLookup 中介查询多行

    正如 DBLookup Mediator 的文档中所述 它仅返回查询的第一行 其他结果 如果有 将被忽略 我想知道是否有 最佳方法 来运行返回多个记录然后处理它们的查询 SELECT FROM X 现在我们正在实现 axis2 服务 但是还
  • 正则表达式匹配文件夹和所有子文件夹

    我需要为备份排除过滤器编写正则表达式以排除文件夹及其所有子文件夹 我需要匹配以下内容 folder1 statistics folder1 statistics folder2 statistics folder2 statistics 我
  • XGBoost - 具有不同曝光/偏移的泊松分布

    我正在尝试使用 XGBoost 对不等长的暴露期生成的数据的索赔频率进行建模 但无法让模型正确处理暴露 我通常会通过将 log exposure 设置为偏移量来做到这一点 你能在 XGBoost 中做到这一点吗 这里发布了类似的问题 xgb
  • firebase 身份验证/无效的自定义令牌

    我正在尝试使用 firebase admin sdk 生成自定义令牌 const uid 91f0bf4c 3e3c 441c a21d 6a7fee341db5 firebaseAdmin auth createCustomToken u
  • 如何训练 libsvm 格式的图像(像素)数据以用于 Java 识别

    我想制作一个 Java 应用程序来使用 libsvm 来识别字符 但是当进入这个过程时 我不明白如何训练图像数据以与 libsvm 一起使用 最近为了学习它 我做了一个测试现有数据 我也创建了32x32基于训练图像数据 将每个像素转换为0
  • C++:如何创建一个接受连接字符串作为参数的函数?

    我可以以某种方式设计我的日志记录功能 使其接受使用 C 的以下形式的串联字符串吗 int i 1 customLoggFunction My Integer i lt lt i lt lt customLoggFunction std co
  • SSIS 中的 UPSERT

    我正在编写一个在 SQL Server 2008 上运行的 SSIS 包 如何在 SSIS 中执行 UPSERT IF KEY NOT EXISTS INSERT ELSE IF DATA CHANGED UPDATE ENDIF ENDI
  • 如何使用 JavaBeans 集合数据集填充图表数据?

    我已经创建了一个工作 jrxml 报告 其中显示了一个由集合的数据集填充的表 List 的 Java bean 现在我想使用相同的数据集来创建图表 初学者的基本条形图 每个 bean 包含 4 个我想在条形图上显示的值 月份 正常时间 旅行
  • `all: unset` 和 `all: revert' 有什么区别

    根据 MDN 在许多情况下 revert 关键字的工作方式与 unset 完全相同 这 唯一的区别是具有由浏览器设置值的属性 或由用户创建的自定义样式表 在浏览器端设置 我不明白浏览器和自定义样式表 浏览器和自定义样式表都可以替换为all
  • Docker-Compose持久数据MySQL

    如果我运行 我似乎无法让 MySQL 数据持久化 docker compose down与以下 yml version 2 services other services data container name flask data ima
  • (如何)我可以计算枚举中的项目吗?

    当我有类似的事情时 我想到了这个问题 enum Folders FA FB FC 并想为每个文件夹创建一个容器数组 ContainerClass m containers 3 m containers FA etc 使用地图会更优雅 std
  • WebDriver Selenium API:当 Element 明显存在时,出现 ElementNotFoundErrorException!

    有时 在关闭 Javascript 的情况下在 WebDriver 上运行测试时 WebDriver 在找到某个元素并尝试单击它时会因 ElementNotFound 错误而崩溃 然而 这个元素显然是存在的 读完这篇文章后 http cod
  • 制作使用项目字段作为键的查找表的惯用方法是什么?

    我有一个收藏Foo struct Foo k String v String 我想要一个HashMap哪个有钥匙 foo k和价值foo 显然 不重新设计是不可能的Foo通过介绍Rc或克隆 复制k fn t1 let foo Foo k k
  • 迁移期间 Laravel 未配置数据库

    这可能是重复的问题 但我对以前的答案没有运气 I just git clone一个 Laravel 项目 现在我尝试做php artisan migrate 它返回以下错误 InvalidArgumentException Database
  • .NET 中的引用是如何定位的?

    NET 使用什么过程在运行时定位引用的程序集 它与在编译期间定位引用的程序集的过程是否不同 我对搜索的位置及其搜索顺序以及可能影响结果的任何参数 配置设置特别感兴趣 NET 应用程序中可以进行三种类型的引用 此答案仅涵盖下面列表中的前两个