Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSBuild: Remove Reference to Assembly added via NuGet

Tags:

c#

.net

msbuild

In the process of moving some legacy code from packages.config to PackageReference.

I have a NuGet package (let's say A.nupkg) that has a reference to a different NuPkg (B.nupkg). B.nupkg includes a reference to Foo.dll.

A project referenced A.nupkg in packages.config, but B.nupkg was not (despite being a transitive dependency). The problem is that the project references a drop-in replacement (same namespace and classes, but including bug fixes) for the Foo API in the form of a Foov2.dll

Now with the change to PackageReference the transitive dependency is picked up, Foo.dll is referenced by the project and we end up with ambiguous references between Foo.dll and Foov2.dll. I can't change the NuGet package (wish I could) so I need a workaround.

I tried adding a target that removes the unwanted reference before building it, but I can't find the right spot to put it - or maybe references from NuGets are handled different to normal references:

  <Target Name="RemoveOutdatedReferences" BeforeTargets="BeforeBuild">
    <Message Importance="High" Text="All references: @(Reference->'%(FileName)'). 
           Sadly no Foo.dll so no wonder I can't remove it."/>
    <ItemGroup>
      <Reference Remove="Foo, Version=1.2.3.4, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb" />
    </ItemGroup>
  </Target>

Alternatively I also tried to remove the whole transitive NuGet package, but using <PackageReference Remove="Foo"/> didn't work either.

like image 216
Voo Avatar asked Sep 12 '25 08:09

Voo


2 Answers

It appears like PackageReference Alias feature is designed specifically for scenarios of namespace collisions.

https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#packagereference-aliases

In some rare instances different packages will contain classes in the same namespace. Starting with NuGet 5.7 & Visual Studio 2019 Update 7, equivalent to ProjectReference, PackageReference supports Aliases. By default no aliases are provided. When an alias is specified, all assemblies coming from the annotated package with need to be referenced with an alias.

like image 97
Andrey Avatar answered Sep 14 '25 21:09

Andrey


You can remove reference in custom target

<Target Name="CustomBeforeBuild" AfterTargets="ResolvePackageDependenciesForBuild">
    <ItemGroup> 
      <ReferenceToBeRemoved Include="@(Reference)" Condition="'%(Reference.PathInPackage)' == 'lib/netstandard2.0/UnneedDll.dll'" />
      <Reference Remove="@(ReferenceToBeRemoved)" />
    </ItemGroup>
    <Message Text="### References to remove: @(ReferenceToBeRemoved) ###" Importance="high" />
  </Target>
like image 33
Vadym Artemchuk Avatar answered Sep 14 '25 21:09

Vadym Artemchuk