如何制作支持用户选择使用DLL或C#源码的.NET类库NuGet包
实现.NET类库DLL/源码二选一包的落地方案
方案一:双独立NuGet包(最推荐,无冲突风险)
该方案完全兼容SDK风格类库,两个包相互独立,不会出现同时引入引发的冲突,用户选择成本极低:
- 解决方案内创建两个SDK风格项目:普通类库项目(命名示例:
Foo)用于打包DLL版本,源码包专用项目(命名示例:Foo.Sources)无需编写业务代码,仅做打包配置 - 所有业务代码统一存放在
Foo项目的代码目录中,Foo.Sources项目通过链接方式引入源码,无需重复维护代码,在Foo.Sources.csproj中添加如下配置:
<ItemGroup> <Compile Include="..\Foo\**\*.cs" Link="%(RecursiveDir)%(Filename)%(Extension)" Pack="true" PackagePath="contentFiles\cs\any\%(RecursiveDir)%(Filename)%(Extension)" /> </ItemGroup>
- 新增
Directory.Build.props文件存放在解决方案根目录,统一配置两个项目的版本号、作者等元数据,修改一次即可同步到两个包,避免版本不一致 - 打包时直接对解决方案执行
dotnet pack命令,即可同时生成两个版本的nupkg文件
用户使用时按需选择安装即可:需要DLL引用安装Foo包,需要源码引用安装Foo.Sources包,完全不会产生冲突。
方案二:单包开关控制(适合轻量维护场景)
如果不想维护两个独立包,可以通过内置配置开关实现单包内二选一:
- 仅维护一个主类库项目,打包时同时将DLL和源码文件打入包内
- 在项目中新增
build目录,创建和包ID同名的props文件(示例:Foo.props),添加如下配置后将该文件设置为打包项,路径对应build目录:
<Project> <PropertyGroup> <!-- 默认启用DLL引用,无需用户额外配置 --> <UseFooSource Condition="'$(UseFooSource)' == ''">false</UseFooSource> </PropertyGroup> <ItemGroup Condition="'$(UseFooSource)' == 'true'"> <!-- 禁用DLL引用,避免冲突 --> <Reference Remove="Foo.dll" /> <!-- 引入包内源码文件 --> <Compile Include="$(MSBuildThisFileDirectory)..\contentFiles\cs\any\**\*.cs" /> </ItemGroup> </Project>
用户使用时默认就是DLL引用模式,如需切换为源码引用,仅需要在自己的项目文件中添加配置<UseFooSource>true</UseFooSource>即可,不会出现同时引用的冲突。
注意事项
- 源码文件打包时必须指定路径为
contentFiles目录,同时设置PackageCopyToOutput为false,避免源码被拷贝到用户项目的输出目录 - 可以将两种使用方式说明写入项目的README.md,打包时嵌入NuGet包,用户安装后即可直接查看使用说明
内容的提问来源于stack exchange,提问作者Vikash Balasubramanian
相关产品推荐
相关产品推荐

