如何实现Nuget包内部分类仅对解决方案内部公开不对消费者暴露
实现方案
完全可以将两个项目合并为单个项目,通过.NET原生的访问控制+打包配置即可实现类可见性的差异化控制,以下是两种适配不同场景的可行方案:
方案1:internal修饰符 + InternalsVisibleTo特性(推荐)
这是最贴合你需求的原生实现,无需复杂配置,完全兼容.NET Standard 2.0:
- 将需要对外暴露给Nuget使用者的类保留
public访问级别,仅用于内部解决方案调用的类统一改为internal访问级别 - 在合并后的项目中添加程序集级别的
InternalsVisibleTo特性,将内部类的访问权限开放给同解决方案下的其他程序集:- 可直接在项目的
AssemblyInfo.cs文件中添加:[assembly: InternalsVisibleTo("你要授权的内部程序集名称")],有多个授权项目可添加多行 - 若使用SDK风格csproj,也可以直接在项目文件中配置,无需手动修改特性文件:
<ItemGroup> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <_Parameter1>你要授权的内部程序集名称</_Parameter1> </AssemblyAttribute> </ItemGroup> - 如果你的程序集配置了强签名,需要在特性参数中补充对应授权程序集的公钥信息,格式为
[assembly: InternalsVisibleTo("程序集名, PublicKey=你的公钥字符串")]
- 可直接在项目的
配置完成后,internal级别的类默认对Nuget使用者完全不可见,只有你指定的同解决方案下的内部项目可以正常访问这些类,无需维护两套高度重合的代码。
方案2:打包排除配置(仅适合本地项目引用场景)
如果你不希望将内部类设为internal,且你的内部项目都是直接引用项目而非引用Nuget包,可以通过打包规则屏蔽内部类:
- 把内部专用的类统一放在单独目录下(例如
Internal目录) - 在csproj中配置该目录下的代码仅参与本地编译,不包含在发布的Nuget包中:
<ItemGroup> <Compile Include="Internal\**\*.cs" Pack="false" /> </ItemGroup>
该方案的局限性在于发布的Nuget包中完全不包含内部类的编译产物,内部项目如果引用Nuget包的话无法访问对应的类。
设计合理性说明
你之前拆分两个高度重合的项目反而会带来代码同步、版本对齐等额外维护成本,合并为单个项目通过访问级别控制可见性是更合理的设计,完全符合.NET的封装规范。
内容的提问来源于stack exchange,提问作者YanivHer
相关产品推荐
相关产品推荐

