Viktor Griph
Viktor Griph

Reputation: 506

Disable transitive PackageReference dependency for a specific MsBuild project

I am migrating an old style MsBuild csproj project to using PackageReference format and have run into a problem with transitive dependencies.

Consider the following Project A reference NuGet package B and C, each containing one single assembly using PackageReference. On Build Project A uses IL merge to incorporate B as public symbols in the A assembly and C as internalized symbols. Project D have a project reference to A.

The transitive dependencies case D to reference A, B and C. When building D, compile errors of the type error CS0433: The type 'X' exists in both 'A' and 'B' occur.

Is there any way to force D to not add an explicit reference to B or C in the scenario above?

Upvotes: 11

Views: 9426

Answers (3)

Michael Bisbjerg
Michael Bisbjerg

Reputation: 1032

I was looking for this too and this answer kept popping up in google searches, but it didn't have the solution I know off (but can never remember), so I'll add my answer for future reference.

PrivateAssets can be used to hide many things, but hiding all is a bad move imo. You want some assets to move transitively, for example, for your app to run after a dotnet publish, you'll need the assemblies you need, at runtime. Hiding all assets means that when publishing, you may miss a few critical things - similar to deleting some files from the output.

From reading MS docs on the subject, I think what I want to hide, in order to not transitively be able to compile up against an assembly (but still have it at runtime), is compile. So I'll set my PrivateAssets to contentfiles;analyzers;build;compile. This should mean that if MyLibraryB depends on NugetPackageA - then MyAppC depending on MyLibraryB will be able to run and publish correctly, without being able to use any classes or code from NugetPackageA.

Note: This of course means that MyLibraryB must not expose any public API that uses types found in NugetPackageA. The consumer won't be able to use those public API's, at least not without themselves also referencing NugetPackageA.

Upvotes: 2

Viktor Griph
Viktor Griph

Reputation: 506

I ended up using a workaround to move the transitive dependency to an alias to get around the compiler error.

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

I tried to use private assets but couldn't get the compiler error to go away in that way.

Upvotes: 7

Leo Liu
Leo Liu

Reputation: 76720

Disable transitive PackageReference dependency for a specific MsBuild project

If I understand you correct, you can try to use property <PrivateAssets>all</PrivateAssets>or PrivateAssets="all" for the PackageReference. If you have a package that's marked with private assets it merely prevents it from flowing to parent project or getting packed.

enter image description here

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

You can check the document Controlling dependency assets and this thread for some details.

Hope this helps.

Upvotes: 4

Related Questions