含项目引用的NuGet包无法解析被引用项目的依赖问题
如何配置MainNugetPkg的.csproj以包含所有递归依赖?
问题场景
我要创建名为MainNugetPkg的NuGet包,解决方案中还有一个OtherProj项目:
MainNugetPkg依赖System.Linq.AsyncOtherProj依赖Enums.NET
我创建了仅引用MainNugetPkg的控制台测试程序Pruebitas,已实现让MainNugetPkg生成时暴露OtherProj的SomeDto类,但运行Pruebitas时抛出System.IO.FileNotFoundException,提示找不到Enums.NET程序集。
测试代码(Program.cs)
using MainNugetPkg; var srv = new MainService(); var ct = srv.GetEmpty() // 调用 AsyncEnumerable.Empty<int>() .ToBlockingEnumerable() .ToList(); Console.WriteLine(ct.Count); // 预期输出 "0" var result = srv.GetNew(MainEnum.One); Console.WriteLine(result.Desc); // 预期输出 "One"
异常信息
System.IO.FileNotFoundException HResult=0x80070002 Mensaje = Could not load file or assembly 'Enums.NET, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7ea1c1650d506225'. El sistema no puede encontrar el archivo especificado. Origen = OtherProj Seguimiento de la pila: en OtherProj.SomeDto`1.get_Desc() en Program.<Main>$(String[] args) en C:\Users\<user>\source\repos\Pruebitas\Pruebitas\Program.cs: línea 11
当前MainNugetPkg的.csproj配置
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <RestoreProjectStyle>PackageReference</RestoreProjectStyle> </PropertyGroup> <ItemGroup> <PackageReference Include="System.Linq.Async" Version="6.0.1" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\OtherProj\OtherProj.csproj"> <PrivateAssets>all</PrivateAssets> </ProjectReference> </ItemGroup> <PropertyGroup> <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);GetMyPackageFiles</TargetsForTfmSpecificBuildOutput> </PropertyGroup> <Target Name="GetMyPackageFiles"> <ItemGroup> <BuildOutputInPackage Include="$(OutputPath)OtherProj.dll"> <PackagePath>lib\$(TargetFramework)\</PackagePath> </BuildOutputInPackage> </ItemGroup> </Target> </Project>
备注
OtherProj.SomeDto.Desc调用了EnumsNET的AsString扩展方法- 移除
PrivateAssets标签后,Pruebitas会报NU1101错误,提示找不到OtherProj - 必须将
MainNugetPkg的bin\Release文件夹添加为包源,Pruebitas才能找到生成的.nupkg
解决方案
方法1:显式添加递归依赖(简单直接)
直接在MainNugetPkg的.csproj中添加OtherProj的依赖包,确保版本与OtherProj中使用的一致:
<ItemGroup> <PackageReference Include="System.Linq.Async" Version="6.0.1" /> <PackageReference Include="Enums.NET" Version="4.0.0" /> <!-- 匹配OtherProj的依赖版本 --> </ItemGroup>
这样Pruebitas安装MainNugetPkg时会自动下载Enums.NET,解决运行时找不到dll的问题。
方法2:自动收集递归依赖(维护友好)
如果不想手动添加依赖,可以通过MSBuild目标自动收集OtherProj的所有包依赖,并将它们作为MainNugetPkg的依赖:
替换MainNugetPkg中原有ProjectReference和目标部分的配置:
<ItemGroup> <ProjectReference Include="..\OtherProj\OtherProj.csproj"> <PrivateAssets>compile;build</PrivateAssets> <!-- 保留编译/构建资产,允许依赖传递 --> <IncludeAssets>all</IncludeAssets> </ProjectReference> </ItemGroup> <PropertyGroup> <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);GetMyPackageFiles</TargetsForTfmSpecificBuildOutput> </PropertyGroup> <Target Name="GetMyPackageFiles"> <ItemGroup> <BuildOutputInPackage Include="$(OutputPath)OtherProj.dll"> <PackagePath>lib\$(TargetFramework)\</PackagePath> </BuildOutputInPackage> </ItemGroup> </Target> <Target Name="CollectTransitivePackageDependencies" BeforeTargets="GenerateNuspec"> <!-- 获取所有项目引用的PackageReference --> <MSBuild Projects="@(ProjectReference)" Targets="GetPackageReferences" Properties="TargetFramework=$(TargetFramework)"> <Output TaskParameter="TargetOutputs" ItemName="TransitivePackageReference" /> </MSBuild> <!-- 将这些依赖添加到当前项目的PackageReference中,确保NuGet包包含它们 --> <ItemGroup> <PackageReference Include="%(TransitivePackageReference.Identity)" Version="%(TransitivePackageReference.Version)" Condition="!Exists('@(PackageReference)'->'%(Identity)' == '%(TransitivePackageReference.Identity)')" /> </ItemGroup> </Target> <!-- 辅助目标:获取项目的PackageReference --> <Target Name="GetPackageReferences"> <ItemGroup> <PackageReferenceOutput Include="@(PackageReference)"> <Identity>%(PackageReference.Identity)</Identity> <Version>%(PackageReference.Version)</Version> </PackageReferenceOutput> </ItemGroup> <Output TaskParameter="ItemGroupOutputs" ItemName="PackageReferenceOutput" /> </Target>
该配置会自动扫描OtherProj的所有包依赖,并将它们加入MainNugetPkg的NuGet依赖列表,Pruebitas安装时会自动获取这些依赖。
关键注意点
- 不能完全移除
PrivateAssets,否则Pruebitas会尝试直接引用OtherProj项目(而非NuGet包),导致NU1101错误 - 保留
GetMyPackageFiles目标,确保OtherProj.dll被打包进MainNugetPkg,无需Pruebitas单独引用OtherProj
内容的提问来源于stack exchange,提问作者Maakarov
相关产品推荐
相关产品推荐

