本文告诉大家如何使用 msbuild 的 ProduceOnlyReferenceAssembly 功能,将某个程序集里面仅导出其中的公开成员定义,而不包含具体的实现的方法
有一些 NuGet 包在发布的时候,为了做一些有趣的业务,期望只是包含程序集的公开成员定义,如公开的方法和公开的属性和枚举等,但是不要包含具体的实现逻辑代码。这样的业务会用在为了减少 NuGet 包的体积,如为了制作插件使用的 NuGet 包。或者说在特定平台上不知道如何实现,只是为了辅助构建通过而已,如我在 Unity 3D 上提供的一些库,表示我不知道如何实现,我只是为了让构建能通过而已
使用 ProduceOnlyReferenceAssembly 可以让输出的程序集 dll 或 exe 里面只是包含了公开的成员的定义,但不包含具体的实现代码。这样的程序集是仅仅作为被引用的程序集使用的,不能被实际调用
下面来告诉大家如何构建这样的程序集,构建有两个方法,第一个是放在 csproj 项目文件里面。如在项目文件里面添加如下代码
添加之后的 csproj 文件代码大概如下
此时执行和之前一样的构建代码,如 msbuild
命令,在构建完成之后输出的 dll 可以看到比之前的小很多。通过 dnspy 等工具,可以看到这个 Dll 里面的所有类的方法都没有具体的实现
但是在很多应用上,更改 csproj 加上以上代码不现实。咱可以通过在构建的时候,修改构建命令来打出仅作为引用的程序集,如执行以下代码
此时构建出来的 dll 就是只读程序集,里面不包含具体的实现
此构建方法适合在库里面进行,如果是在一个大的应用项目里面构建,如果发现构建不通过,就需要你了解很多构建相关的知识才能解决哈
更多请看 C# Compiler Options - code generation options
官方文档是 Reference assemblies
更多关于 Roslyn 请看 手把手教你写 Roslyn 修改编译
如果不想从源代码生成,期望从 DLL 里面重新导出,请参阅 dotnet 使用 Refasmer 从现有的 DLL 里面导出公开的成员组装出新的仅作为引用用途的程序集
此行为在 dotnet 6 被变更,详细请参阅:
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。 欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。