尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Microsoft.Extensions.DependencyModel 完全指南:解析 .deps.json 依赖清单与动态编译实践
语言运行时标准库JIT编译编译器【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址https://gitcode.com/GitHub_Trending/runtime6/runtime点击查看免费下载导读本指南以 .NET 运行时仓库中 Microsoft.Extensions.DependencyModel 包 为切入点系统讲解 .deps.json 依赖清单的读取机制、DependencyContext对象模型以及如何利用CompilationLibrary.ResolveReferencePaths()在运行时还原编译期引用程序集列表从而支撑基于 Roslyn Emit API 的动态编译等高级场景。读完本文你将掌握依赖清单的 JSON 结构、加载与解析链路、程序集路径解析策略并能直接写出可运行的动态编译辅助代码。什么是 .deps.json为什么需要 DependencyModel当一个 .NET 应用程序被编译时SDK 会生成一个 JSON 清单文件ApplicationName.deps.json其中包含应用的全部依赖信息目标框架、运行时依赖、编译期引用程序集等。这份清单是宿主host在运行时定位程序集、加载共享框架与 NuGet 包的关键依据。Microsoft.Extensions.DependencyModel包提供的正是读取这份清单的抽象层。它把.deps.json反序列化为强类型的DependencyContext对象使应用代码能够在运行时查询当前应用的编译库CompilationLibrary编译期引用的程序集运行时库RuntimeLibrary实际加载到运行时的程序集目标框架信息与运行时回退图RuntimeGraph。典型应用场景是动态编译例如使用 Roslyn Emit API 在运行时把 C# 源码编译成程序集此时需要以和主应用完全相同的依赖集作为编译引用。通过DependencyContext.Default.CompileLibraries即可拿到主应用编译期引用的全部程序集路径直接喂给CSharpCompilation。启用编译上下文PreserveCompilationContext默认情况下依赖清单只包含目标框架和运行时依赖信息不含编译期引用程序集。要让CompileLibraries有内容必须在项目文件中显式开启PropertyGroup PreserveCompilationContexttrue/PreserveCompilationContext /PropertyGroup该属性是 SDK 项目的 MSBuild 属性之一开启后 SDK 会额外把编译期使用的引用程序集reference assemblies信息写入.deps.json的编译目标compile target节点中。快速上手打印当前应用的编译引用程序集在项目文件中加入PreserveCompilationContexttrue/PreserveCompilationContext后运行以下程序即可列出动态编译所需的全部引用路径using System; using Microsoft.Extensions.DependencyModel; class Program { static void Main() { Console.WriteLine(Compilation libraries:); Console.WriteLine(); foreach (CompilationLibrary lib in DependencyContext.Default.CompileLibraries) { foreach (string path in lib.ResolveReferencePaths()) { Console.WriteLine(path); } } } }输出中每一行都是磁盘上真实的程序集绝对路径如.../packs/Microsoft.NETCore.App.Ref/.../ref/net8.0/System.Runtime.dll。这些路径可以直接作为MetadataReference传给 Roslyn 的CSharpCompilation从而保证动态编译的引用与主应用完全一致。对象模型DependencyContext 及其核心类型DependencyContext是包的核心入口类型定义在 DependencyContext.cs其公开属性如下属性类型说明TargetTargetInfo目标框架与运行时信息框架名、运行时标识符、签名、是否可移植CompilationOptionsCompilationOptions编译选项快照用于还原编译环境CompileLibrariesIReadOnlyListCompilationLibrary编译期引用库需开启 PreserveCompilationContextRuntimeLibrariesIReadOnlyListRuntimeLibrary运行时加载库RuntimeGraphIReadOnlyListRuntimeFallbacksRID 回退链如win-x64 → win → any获取方式DependencyContext.Default静态懒加载LazyDependencyContext?基于入口程序集加载默认上下文。注意该方法带有[RequiresAssemblyFiles]特性——单文件发布single-file场景下返回 null调用方必须处理空值见 DependencyContext.cs。DependencyContext.Load(Assembly)为任意程序集加载其对应的依赖上下文内部委托给DependencyContextLoader.Default.Load(assembly)。Merge(other)将两个上下文合并按库名去重库名比较忽略大小写用于叠加多个.deps.json的场景。Library 基类CompilationLibrary与RuntimeLibrary都继承自 Library.cs 中的Library基类公共字段包括Type库类型如packageNuGet 包、project/msbuildproject项目引用、referenceassembly、referenceName、Version、Hash/HashPath库的标识信息Dependencies该库的依赖列表Serviceable是否可服务化影响运行时回退到共享框架的决策Path、RuntimeStoreManifestName库在包缓存中的位置信息。RuntimeLibrary 与运行时资产RuntimeLibrary.cs 在Library基础上增加了三组资产RuntimeAssemblyGroups按 RID 分组的托管程序集RuntimeAssetGroupNativeLibraryGroups按 RID 分组的原生库ResourceAssemblies资源程序集。配合 DependencyContextExtensions.cs 中的扩展方法如GetRuntimeAssemblyNames(runtimeIdentifier)、GetDefaultNativeAssets()可以按指定 RID 及其回退链解析出实际应使用的资产集合——解析逻辑会依次尝试rid → 回退rid → 无RID的默认组。CompilationLibrary 与引用路径解析CompilationLibrary.cs 的核心方法是ResolveReferencePaths()它把清单中的相对程序集名解析为磁盘上的绝对路径public IEnumerablestring ResolveReferencePaths() public IEnumerablestring ResolveReferencePaths(params ICompilationAssemblyResolver[] customResolvers)无参版本使用内置的默认解析器链带参版本允许先尝试自定义解析器TryResolveAssemblyPaths返回 true 即成功失败后再回落到默认链。若最终仍无法解析会抛出InvalidOperationException资源字符串LibraryLocationNotFound见 Strings.resx。默认解析器链由CompositeCompilationAssemblyResolver按顺序组合见 CompilationLibrary.csAppBaseCompilationAssemblyResolver在应用基目录含发布时生成的refs/目录、共享运行时目录中按文件名查找仅处理project、msbuildproject、package、referenceassembly、reference这几类库见 AppBaseCompilationAssemblyResolver.csReferenceAssemblyPathResolver针对referenceassembly类型解析到 .NET 引用程序集目录PackageCompilationAssemblyResolver针对package类型在全局 NuGet 缓存NuGet 包文件夹中定位。加载与解析链路从文件到对象依赖清单的读取由 DependencyContextLoader.cs 驱动整体流程如下Assembly → 是否为入口程序集 ├─ 是 → 读取 APP_CONTEXT_DEPS_FILES 指定的应用 .deps.json即 entryPointDepsLocation └─ 否 → ① 查找嵌入资源 程序集名.deps.json ② 或查找程序集 Location/CodeBase 同目录下的 .deps.json 文件 成功读取后 → 叠加 NonApplicationPaths额外的 deps 文件例如共享框架 FX_DEPS_FILE → 返回 Merge 后的 DependencyContext关键实现细节路径来源应用与共享框架的 deps 文件路径来自 AppDomain 数据APP_CONTEXT_DEPS_FILES分号分隔首项为应用与FX_DEPS_FILE共享框架见 DependencyContextPaths.cs。JSON 解析DependencyContextJsonReader.cs 基于System.Text.Json的Utf8JsonReader手写流式解析器支持处理 UTF-8 BOM并通过ArrayPoolbyte复用缓冲区、用_stringPool去重字符串以降低分配。解析时依次读取顶层节点runtimeTarget、compilationOptions、targets、libraries、runtimes其中targets分为编译目标RID-less与运行时目标带/分隔符的 RID 目标如net8.0/win-x64分别映射为CompileLibraries与RuntimeLibraries。编译选项compilationOptions节点被反序列化为 CompilationOptions.cs 中定义的类型包含Defines、LanguageVersion、AllowUnsafe、WarningsAsErrors、Optimize、KeyFile、DelaySign、PublicSign、DebugType、EmitEntryPoint、GenerateXmlDocumentation等字段——这些正是用 Roslyn 还原编译环境时所需的参数。若清单中缺失该节点则回落到CompilationOptions.Default。实战基于 Roslyn 的动态编译结合上述知识一个完整的动态编译辅助代码如下示意using System; using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.Extensions.DependencyModel; static class DynamicCompiler { public static CSharpCompilation CreateCompilation(string source, string assemblyName) { // 1. 获取主应用的编译期引用程序集路径 ListMetadataReference references new(); foreach (CompilationLibrary lib in DependencyContext.Default.CompileLibraries) { foreach (string path in lib.ResolveReferencePaths()) { references.Add(MetadataReference.CreateFromFile(path)); } } // 2. 还原编译选项语言版本等 CSharpCompilationOptions options new(OutputKind.DynamicallyLinkedLibrary); // 3. 创建编译对象 return CSharpCompilation.Create( assemblyName, new[] { CSharpSyntaxTree.ParseText(source) }, references, options); } }运行前提项目需开启PreserveCompilationContexttrue/PreserveCompilationContext且不要以单文件发布否则DependencyContext.Default为 null需自行判空并回退方案。该方案保证了动态编译的引用集合与主应用完全一致避免少引用一个包导致编译失败的问题。测试与验证仓库为该包配备了完整测试集位于 Microsoft.Extensions.DependencyModel.Tests可用来验证上述行为DependencyContextJsonReaderTest.cs验证.deps.json各节点的解析结果DependencyContextLoaderTests.cs验证加载链路的路径探测与合并逻辑PackageResolverTest.cs、AppBaseResolverTests.cs、ReferenceAssemblyResolverTests.cs分别验证三种解析器对package/project/referenceassembly等类型的路径解析。测试还通过FileSystemMockBuildermocks/FileSystemMockBuilder.cs与EnvironmentMockBuilderEnvironmentMockBuilder.cs构造虚拟文件系统从而在无需真实文件的情况下断言解析结果。补充包内的其他实用类型TargetInfo封装框架名、运行时标识符与是否可移植portable标记。RuntimeFallbacks描述某个 RID 的回退链例如win-x64可回退到win、再到无 RID 的通用资产。ResourceAssembly资源程序集的路径与 locale 信息。RuntimeFile运行时资产文件描述路径、程序集版本、文件版本。命名空间Microsoft.Extensions.DependencyModel.Resolution下的ICompilationAssemblyResolver接口允许自定义程序集路径解析策略适合非标准部署布局如自定义包缓存、离线源。适用前提与限制PreserveCompilationContext仅在 SDK 风格项目Microsoft.NET.Sdk中生效开启会增大.deps.json体积并暴露编译期引用信息。单文件发布single-file下DependencyContext.Default返回null源码中[RequiresAssemblyFiles]标注了该行为相关代码需做空值保护。依赖清单的最终格式由 .NET SDK 生成本包只负责读取若清单缺失编译目标节点CompileLibraries将为空。小结Microsoft.Extensions.DependencyModel以约三十个源文件见 src 目录实现了对.deps.json依赖清单的完整读取能力从DependencyContextLoader的路径探测到DependencyContextJsonReader的高效 JSON 解析再到三种内置解析器的程序集路径还原构成了一条清晰、可扩展的调用链。对于需要在运行时获得与主应用一致的编译引用集的动态编译、代码分析、构建工具类应用这是官方推荐的标准化方案。赞分享语言运行时标准库JIT编译编译器【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址https://gitcode.com/GitHub_Trending/runtime6/runtime点击查看免费下载相关推荐Jaeger-Client-Go扩展开发自定义Reporter与Sampler实现指南Jaeger Client Go扩展开发自定义Reporter与Sampler实现指南 Jaeger Client Go是一个功能强大的分布式追踪客户端库它DeepChem 依赖环境全解硬性要求与软性依赖清单requirements.rst 实践指南DeepChem 依赖环境全解硬性要求与软性依赖清单requirements.rst 实践指南 DeepChem 是一个面向药物发现、量子化学、材料科学与人工智能深度学习机器学习生物信息学科学计算Wireshark依赖库编译静态与动态链接完全指南Wireshark依赖库编译静态与动态链接完全指南 引言 在网络分析领域Wireshark是一款功能强大的开源工具它能够捕获和分析网络数据包。Wiresh网络通信创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

STM32CubeIDE安装配置与HAL开发全链路解析

STM32CubeIDE安装配置与HAL开发全链路解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/20 15:25:26
YOLOv11+ByteTrack+单目测距:自动驾驶感知融合实战与踩坑指南

YOLOv11+ByteTrack+单目测距:自动驾驶感知融合实战与踩坑指南

简介:面向自动驾驶感知、目标检测与跟踪领域的工程师与研究者,这份PDF资源系统梳理了YOLOv11多目标跟踪与距离测量融合方案的完整技术路径。文档共41页,作为单文件PDF约2MB,结构清晰,支持目录章节跳转与大纲快速定位。…

📅 2026/9/20 15:20:24
283页Java面试核心知识点解析:HashMap、JVM与并发编程实战

283页Java面试核心知识点解析:HashMap、JVM与并发编程实战

简介:这是一份面向Java面试者的核心知识点整理文档,完整覆盖JVM内存区域(程序计数器、虚拟机栈、本地方法区、堆、方法区/永久代)的线程私有与共享划分、JVM运行时内存(新生代Eden、ServivorFrom、ServivorTo及MinorGC…

📅 2026/9/20 15:20:24
MORE NEWS

更多资讯

📰

MATLAB实现结构光三维重建:三频四步相移法全解析

前阵子有个研究生来问我,MATLAB做结构光三维重建到底该从哪儿入手。很多新手一上来就翻论文,三频四步相移法、多频外差、包裹相位展开这些术语看得头大,真正能跑的代码却拼不出一套。其实这套方法远没有想象中那么神秘:投影仪往被…

📰

IPX8防水TYPE-C连接器设计规范:从密封到信号完整性的工程全解

简介:IPX8防水Type-C连接器产品设计规范是一份由深圳市长盈精密技术有限公司工程团队编制的技术文件,面向连接器结构设计、工艺开发与品控人员,用于避免设计失效、压缩开发周期并降低试错成本。文档覆盖设计目的、防水等级定义、主要功能参数…

📰

初二数学动点问题专项练习:四类模型与答案解析

简介:面向初二学生及初中数学教师,聚焦几何动点问题这一易错难点,系统整理了含答案解析的典型练习。压缩包内为1个doc文档,大小约454KB,文档按题型分类编排,涵盖梯形、正方形、直角三角形、射线动点等常见动…

📰

C语言学习路线与实战指南:从基础语法到环境配置、算法与嵌入式应用

简介:谭浩强编著的《C语言程序设计(第五版)》共533页,适合高校学生、自学者及备考计算机等级考试的读者系统学习C语言。内容覆盖数据类型、运算符、顺序/选择/循环结构、数组、函数、指针、结构体、位运算及文件操作等核心模块&am…

📰

SuperClaude Framework 的 /sc:troubleshoot 命令实战:从问题诊断到安全修复的完整排查方法论

开发工具CLIAI 技能/插件测试人工智能AI 评测 【免费下载链接】SuperClaude_Framework A configuration framework that enhances Claude Code with specialized commands, cognitive personas, and development methodologies. 项目地址: https://gitcode.com/gh_m…

📰

Omost 上手指南:让 LLM 替你写代码画图

Omost 上手指南:让 LLM 替你写代码画图 【免费下载链接】Omost Your image is almost there! 项目地址: https://gitcode.com/GitHub_Trending/om/Omost 提示词调了半小时,出来的图还是差口气:主体位置不对,背景抢戏&#…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬