企业品牌网站营销,做网站开发要注册,教育智慧城市型网站开发,h5网站建设 网站定制开发.NET 中的引用程序集Intro在 .NET 里有一种特殊的程序集叫做 ReferenceAssembly(引用程序集)#xff0c;引用程序集#xff08;Reference Assemblies#xff09; 是一种特殊类型的程序集#xff0c;它只包含表示库的公共 API 所需的最少元数据量。它们包括在生成工具中引用… .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 的 attributeReference Assembly再看一下 JsonNode 的实现我们再找一个实现的程序集对比一下Implementation assembly由于它们不包含任何实现因此无法加载引用程序集用于执行。如果尝试这样做则会导致 System.BadImageFormatException可能会遇到 Reference assemblies can only be loaded in the Reflection-only loader context. 这样的错误。如果要检查引用程序集的内容你可将其加载到 .NET Framework 中的仅反射上下文中使用 Assembly.ReflectionOnlyLoad 方法或者加载到 .NET Core 中的 MetadataLoadContext。More经常看源码的童鞋一定会注意到dotnet/runtime 中很多的类库的结构都是类似下面这样的runtime library structure大家会看到第一个目录是 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?vEBpY1UMHDY8listPLRAdsfhKI4OX1cBGL2IXuEq1yzpDyKlwfindex1t3s之后才恍然大悟原来如此。。。虽然视频是以 .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#L8https://github.com/dotnet/runtime/blob/89962a54d60e4d9c9837012d1729c5a72ec748cd/eng/referenceAssemblies.props#L22Referenceshttps://github.com/dotnet/docs/pull/14393https://github.com/dotnet/docs/issues/2638https://github.com/dotnet/roslyn/blob/main/docs/features/refout.mdhttps://docs.microsoft.com/en-us/dotnet/standard/assembly/reference-assemblieshttps://docs.microsoft.com/zh-cn/dotnet/standard/assembly/reference-assemblieshttps://www.youtube.com/watch?vEBpY1UMHDY8listPLRAdsfhKI4OX1cBGL2IXuEq1yzpDyKlwfindex1t3s