从packages.config升级到PackageReference后NuGet包子文件夹DLL引用异常
解决PackageReference不识别NuGet包子文件夹DLL的问题
这个坑我之前迁移项目的时候也踩过!确实,packages.config会把包里所有DLL都自动加进项目引用,但PackageReference默认只扫描lib\<target-framework>根目录下的DLL,子文件夹里的会被直接忽略,导致调用相关功能的代码编译报错。下面给你几个可行的解决办法:
方法1:修改NuGet包(适用于你能控制包源码的情况)
如果这个NuGet包是你们团队自己维护的,最根本的解决方式是调整包的结构和配置:
- 把子文件夹里的DLL直接移到
lib\net45根目录下(只要DLL名称不冲突就行); - 或者在
.nuspec文件里通过<files>节点明确声明所有需要被识别的DLL,同时添加<reference>标记让NuGet知道要引用这些文件:
重新打包发布后,<files> <file src="lib\net45\some.dll" target="lib\net45" /> <file src="lib\net45\xxx\other.dll" target="lib\net45\xxx"> <reference include="other" /> </file> </files>PackageReference就能正确识别所有需要的DLL了。
方法2:手动在项目文件中添加引用
如果没法修改原包,直接编辑你的.csproj文件,手动添加对子文件夹DLL的引用:
<ItemGroup> <Reference Include="other"> <!-- 替换成实际的包ID和版本号 --> <HintPath>$(NuGetPackageRoot)\your-package-id\1.0.0\lib\net45\xxx\other.dll</HintPath> <Private>True</Private> </Reference> </ItemGroup>
这里的$(NuGetPackageRoot)是NuGet的内置变量,会自动指向本地包缓存路径,不用写死绝对路径。
方法3:通过MSBuild目标自动处理(适合子文件夹较多的场景)
如果包里子文件夹和DLL数量很多,手动加引用太麻烦,可以在.csproj里加一个MSBuild目标,自动扫描包的子文件夹并添加引用:
<Target Name="AddSubfolderReferences" BeforeTargets="ResolveReferences"> <ItemGroup> <!-- 替换成你的包ID和目标框架 --> <SubfolderDlls Include="$(NuGetPackageRoot)\your-package-id\*\lib\net45\**\*.dll" Exclude="$(NuGetPackageRoot)\your-package-id\*\lib\net45\*.dll" /> <Reference Include="%(SubfolderDlls.Filename)"> <HintPath>%(SubfolderDlls.FullPath)</HintPath> <Private>True</Private> </Reference> </ItemGroup> </Target>
这个目标会在构建前自动扫描包内所有子文件夹的DLL,并批量添加为项目引用。
另外还要注意:有些年代比较久的包可能完全没适配PackageReference,如果上面的方法都不行,可以考虑联系包作者更新,或者自己下载包的nupkg文件,解压后调整结构再重新打包使用。
内容的提问来源于stack exchange,提问作者MBL
相关产品推荐
相关产品推荐

