NuGet发布程序包时如何不发布内部依赖项目且隐藏内部类型
这个需求完全可以实现,不需要合并两个项目的代码,也不需要逐个修改Domain层类的访问修饰符,按下面的步骤配置即可。
1. 配置Client对Domain的项目引用规则
打开Client项目的.csproj文件,找到对Domain项目的ProjectReference节点,修改为如下配置:
<ProjectReference Include="..\Domain\Domain.csproj"> <!-- 打包时不将Domain作为独立依赖传递给外部项目 --> <PrivateAssets>all</PrivateAssets> <!-- 编译时引用Domain,但最终输出目录不生成独立的Domain.dll --> <ExcludeAssets>runtime</ExcludeAssets> </ProjectReference>
这个配置可以避免Nuget把Domain标记为Client包的外部依赖,外部项目安装Client时不会要求拉取Domain的独立包。
2. 配置程序集合并+自动修改Domain类型可见性
推荐使用ILRepack完成程序集合并,不需要修改Domain层任何代码,哪怕Domain里的类全是public,合并时会自动将Domain的所有类型标记为internal,仅Client程序集可访问,外部项目完全看不到这些类型。
首先在Client项目中安装ILRepack的MSBuild集成包:
dotnet add package ILRepack.MSBuild.Task
安装完成后,在Client项目的.csproj文件中添加如下构建目标,放在</Project>标签之前即可:
<Target Name="MergeDomainAssembly" AfterTargets="Build"> <ILRepack OutputType="Library" MainAssembly="$(OutputPath)$(AssemblyName).dll" OutputAssembly="$(OutputPath)$(AssemblyName).dll" InputAssemblies="$(OutputPath)Domain.dll" <!-- 核心配置:将合并进来的Domain程序集所有类型改为internal --> Internalize="true" /> </Target>
配置完成后,正常编译、打包Client项目即可,最终生成的Client程序集是单文件,已经包含了Domain的所有逻辑。
效果验证
打包生成的nupkg包上传到Artifactory后,外部项目安装使用时可达到预期效果:
- 不会抛出找不到Domain程序集的错误
- 代码智能提示不会展示Domain层的任何类型,外部代码无法直接访问Domain的类、接口等成员
- 本地开发时仍然保留Client、Domain两个独立项目的代码结构,开发体验和之前没有区别
如果你不想引入第三方合并工具,也可以用无依赖方案:在Domain项目中添加程序集级别特性[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("你的Client程序集名称")],再批量将Domain中所有顶级类的public修饰符删除即可——C#中顶级类型默认访问级别就是internal,批量替换的效率远高于逐个修改类的访问修饰符。不过这个方案需要额外配置程序集内嵌加载逻辑,不如直接用ILRepack简便。
内容的提问来源于stack exchange,提问作者ewok

