为特定的MsBuild项目禁用传递性PackageReference依赖

7
我正在将一种旧式的 MsBuild csproj 项目迁移到使用 PackageReference 格式,并在传递依赖方面遇到了问题。
考虑以下情况,项目 A 引用 NuGet 包 B 和 C,每个包均使用 PackageReference 包含一个单独的程序集。在构建时,项目 A 使用 IL 合并将 B 合并为 A 程序集中的公共符号,将 C 合并为内部化符号。项目 D 有一个对 A 的项目引用。
传递依赖使得 D 引用了 A、B 和 C。在构建 D 时,会出现以下类型的编译错误: error CS0433: The type 'X' exists in both 'A' and 'B'
是否有任何方法可以强制 D 在上述场景中不添加对 B 或 C 的显式引用?
3个回答

4

我最终使用了一个解决方法,将传递依赖项移动到别名中以避免编译器错误。

<Target Name="ChangeAliasesOfBNameAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
  <ItemGroup>
    <ReferencePath Condition="'%(FileName)' == 'B'">
      <Aliases>nonmerged</Aliases>
    </ReferencePath>
  </ItemGroup>
</Target>

我试图使用私有资源,但无法以这种方式消除编译器错误。


1
这对我有用!我没有意识到给我不想使用的包设置别名会导致另一个包中的类型可用,所以我一直试图为我想要的包设置别名(这是个问题,因为它是 Microsoft.NETCore.Platforms...)。 - Salem
哇,令人印象深刻。你的方法帮助我解决了一个"模糊引用"错误。非常感谢你。 - undefined

3

针对特定的MsBuild项目禁用传递性PackageReference依赖

如果我的理解是正确的,您可以尝试在PackageReference中使用属性<PrivateAssets>all</PrivateAssets>PrivateAssets="all"。如果您有一个标记有私有资产的包,它只是防止其流向父项目或被打包。

enter image description here

<PackageReference Include="B" Version="1.0.0" PrivateAssets="all">
<PackageReference Include="C" Version="1.0.0" PrivateAssets="all">

你可以查看控制依赖资产此帖子中的一些详细信息。
希望这可以帮助到你。

1
我尝试在A对B和C的引用中使用PrivateAssets,但仍然出现了冲突类型。最终我使用了这里的解决方法https://github.com/NuGet/Home/issues/4989#issuecomment-310565840,在一个未使用的别名中放置了B。 - Viktor Griph
1
@ViktorGriph,很高兴听到您已经解决了这个问题。您能否将您的解决方法发布为答案,这对于阅读本帖子的其他社区成员会很有益,并且更容易找到答案:)。 - Leo Liu
这对我们来说并没有解决问题。我们需要一种方法来忽略PackageReference范例中的传递依赖,类似于在packages.config范例中所做的那样,只需删除nuget添加的引用即可。PrivateAssets仅影响输出目录,不影响依赖关系图。 - Tim Sparkles

1
我也在寻找这个答案,它在谷歌搜索中一直出现,但它没有我知道的解决方案(但我总是记不住),所以我会为将来的参考添加我的答案。
PrivateAssets 可用于隐藏许多东西,但我认为隐藏所有内容是一个糟糕的举动。你需要一些资产在运行时可以移动,例如,在 dotnet publish 之后运行应用程序,你需要所需的程序集。隐藏所有资产意味着在发布时可能会错过一些关键的东西,类似于从输出中删除某些文件。

从阅读MS docs的内容来看,我认为我想要隐藏的是compile,以便不能在编译程序集时进行传递(但仍然可以在运行时使用它)。因此,我将我的PrivateAssets设置为contentfiles;analyzers;build;compile。这意味着如果MyLibraryB依赖于NugetPackageA,那么依赖于MyLibraryBMyAppC将能够正确运行和发布,而不会使用NugetPackageA中的任何类或代码。

注意:这当然意味着MyLibraryB不能公开使用NugetPackageA中找到的类型的任何公共API。消费者将无法使用这些公共API,至少不会在没有自己引用NugetPackageA的情况下使用。


这是我们的情况,我们要隐藏第三方依赖项,使其类型不出现在我们的消费者范围内,同时仍然能够自己使用它。以这种方式设置PrivateAssets似乎起到了作用。 - T2PS
这是我们的情况,我们要隐藏第三方依赖项,使其类型不出现在我们的消费者范围内,同时我们自己仍然能够使用它。以这种方式设置PrivateAssets似乎起到了作用。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接