当前位置:网站首页>.NET 中的引用程序集
.NET 中的引用程序集
2022-06-27 09:35:00 【dotNET跨平台】
.NET 中的引用程序集
Intro
在 .NET 里有一种特殊的程序集叫做 ReferenceAssembly(引用程序集),引用程序集(Reference Assemblies) 是一种特殊类型的程序集,它只包含表示库的公共 API 所需的最少元数据量。它们包括在生成工具中引用程序集时所需的所有成员的声明,但不包括所有成员实现以及对其 API 协定没有明显影响的私有成员的声明。相比较下,常规程序集称为“实现程序集” (implementation assemblies)。
Why
既然我们有实现程序集,为什么还要有引用程序集呢?
使用引用程序集,开发人员可以生成面向特定库版本的程序,而无需具有该版本的完整实现程序集。因为不包含实现,引用程序集会更小一些,加载和解析都会更快一些。
这类似于我们和第三方的开发者约定的 API 规范,我们可以先给出 API 的请求和响应而无需提供实现以不 block 第三方开发者的进度,毕竟他们只关心 API 是什么样的而不关心实现。
若要使用项目中的某些 API,必须添加对其程序集的引用。可以将引用添加到实现程序集,也可以将其添加到引用程序集。建议在引用程序集可用时使用它。这样做可确保仅使用目标版本中受支持的 API 成员,即供 API 设计人员使用。使用引用程序集可确保不依赖于实现详细信息。
How
在 .NET Core 3.0 之前很多程序集都是发布 NuGet 包的,对于 .NET Core 3.0 和更高版本,核心框架的引用程序集位于 Microsoft.NETCore.App.Ref 包中,一般情况下是不需要的,因为引用程序集也会随着 .NET SDK 一起发布,你可以在 SDK 的安装目录下的 packs
目录下找到对应框架版本的引用程序集
下面是我电脑上 SDK 里的框架引用程序集的一个示例
对于引用程序集只能用于编译,这种程序集会有一些特殊,反编译的话会看到有一个 ReferenceAssembly 的程序集 Attribute,下面是我从上面的目录中找的 System.Text.Json
的反编译结果,可以看到有一个 ReferenceAssembly
的 attribute
再看一下 JsonNode
的实现
我们再找一个实现的程序集对比一下
由于它们不包含任何实现,因此无法加载引用程序集用于执行。如果尝试这样做,则会导致 System.BadImageFormatException,可能会遇到 Reference assemblies can only be loaded in the Reflection-only loader context. 这样的错误。
如果要检查引用程序集的内容,你可将其加载到 .NET Framework 中的仅反射上下文中(使用 Assembly.ReflectionOnlyLoad 方法),或者加载到 .NET Core 中的 MetadataLoadContext。
More
经常看源码的童鞋,一定会注意到,dotnet/runtime 中很多的类库的结构都是类似下面这样的
大家会看到第一个目录是 ref
,也就是用来生成引用程序集的,src
则是包含了实现的项目源码,test
则是一些测试用例 https://github.com/dotnet/runtime/blob/89962a54d60e4d9c9837012d1729c5a72ec748cd/src/libraries/Microsoft.Extensions.Configuration/
ref
项目引用的其他项目也都是直接引用的 ref
项目 https://github.com/dotnet/runtime/blob/89962a54d60e4d9c9837012d1729c5a72ec748cd/src/libraries/Microsoft.Extensions.Configuration/ref/Microsoft.Extensions.Configuration.csproj
查看 ref 项目的代码,可以发现和反编译的效果是一样的,都是空实现或者 throw null https://github.com/dotnet/runtime/blob/89962a54d60e4d9c9837012d1729c5a72ec748cd/src/libraries/Microsoft.Extensions.Configuration/ref/Microsoft.Extensions.Configuration.cs#L7
最近在做 dotnet-exec 这个小工具的时候就遇到了引用程序集的问题,起初没怎么理解这个引用程序集,在编译代码时使用的是引用程序集,在执行代码时也是用的引用程序集,在执行时 load 程序集的时候就报了前面提到的
BadImageException
Reference assemblies can only be loaded in the Reflection-only loader context.
在看到 Youtube 上这个介绍 Reference Assembly 的视频(https://www.youtube.com/watch?v=EBpY1UMHDY8&list=PLRAdsfhKI4OX1cBGL2IXuEq1yzpDyKlwf&index=1&t=3s)之后才恍然大悟,原来如此。。。虽然视频是以 .NET Framework 为例讲解的,.NET Core 也类似,感兴趣的可以看一下
在 VS 里经常会遇到 F12 之后看到的实现都是 throw null
,猜测也是因为这个原因,在编译时 VS 使用的是引用程序集来提高性能
最后有没有好奇 ref 项目和 src 项目的差别在哪里?表面上看 ref 项目文件里的东西好像没什么特别的啊,利用了之前我们提到过的 Directory.Build.props 来为大多数项目统一配置了,感兴趣的同学可以根据下面的链接自己探索一下
https://github.com/dotnet/runtime/blob/89962a54d60e4d9c9837012d1729c5a72ec748cd/src/libraries/Directory.Build.props#L8
https://github.com/dotnet/runtime/blob/89962a54d60e4d9c9837012d1729c5a72ec748cd/eng/referenceAssemblies.props#L22
References
https://github.com/dotnet/docs/pull/14393
https://github.com/dotnet/docs/issues/2638
https://github.com/dotnet/roslyn/blob/main/docs/features/refout.md
https://docs.microsoft.com/en-us/dotnet/standard/assembly/reference-assemblies
https://docs.microsoft.com/zh-cn/dotnet/standard/assembly/reference-assemblies
https://www.youtube.com/watch?v=EBpY1UMHDY8&list=PLRAdsfhKI4OX1cBGL2IXuEq1yzpDyKlwf&index=1&t=3s
边栏推荐
- unity--newtonsoft.json解析
- Five page Jump methods for wechat applet learning
- Quick start CherryPy (1)
- Win10 add right-click menu for any file
- Bluetooth health management device based on stm32
- Tdengine invitation: be a superhero who uses technology to change the world and become TD hero
- 反编译jar包,修改后重新编译为jar包
- Vector:: data() pointer usage details
- 小白也能看懂的网络基础 03 | OSI 模型是如何工作的(经典强推)
- unity--newtonsoft. JSON parsing
猜你喜欢
[MySQL basic] general syntax 1
快捷键 bug,可复现(貌似 bug 才是需要的功能 [滑稽.gif])
【生动理解】深度学习中常用的各项评价指标含义TP、FP、TN、FN、IoU、Accuracy
Win10 add right-click menu for any file
【OpenCV 例程200篇】212. 绘制倾斜的矩形
Bluetooth health management device based on stm32
为智能设备提供更强安全保护 科学家研发两种新方法
[system design] proximity service
Advanced mathematics Chapter 7 differential equations
Semi supervised learning—— Π- Introduction to model, temporary assembling and mean teacher
随机推荐
Tdengine invitation: be a superhero who uses technology to change the world and become TD hero
Nosql 数据库 -Redis 安装
如何获取GC(垃圾回收器)的STW(暂停)时间?
Design of multiple classes
C # solve the relative path problem using SQLite
[diffusion model]
Use aspese Cells convert Excel to PDF
一次线上移动端报表网络连接失败问题定位与解决
JS 客户端存储
openpyxl表格读取实例
Apache POI的读写
Markem Imaje Marken IMAS printer maintenance 9450e printer maintenance
The largest rectangle in the bar graph of force buckle 84
unity--newtonsoft. JSON parsing
TDengine 邀请函:做用技术改变世界的超级英雄,成为 TD Hero
[vivid understanding] the meanings of various evaluation indicators commonly used in deep learning TP, FP, TN, FN, IOU and accuracy
Vector:: data() pointer usage details
ThreadLocal digs its knowledge points again
ucore lab4
win10为任意文件添加右键菜单