A Project Reference magically ends up using a NuGet Reference

843 views Asked by At

I've got this weird issue adding a Project Reference via a relative path in csproj file and/or the DLL directly. It keeps reverting back to the NuGet DLL in my Nuget folder: C:\Users\jeremy.nuget\packages\

Steps to cause problem:

  1. Delete a Base NuGet Project Ref
  2. Add a reference to the Base DLL of a Project in a different Solution.
  3. Check the Path to the referenced DLL's properties and it still points to the NuGet not the DEBUG Project Ref.

I've turned off the NuGet Source and Visual Studio still uses the NuGet.

If I rename the NuGet DLL and then reference by Project specifying the Debug folder DLL it then fails! So what is causing it to look up the NuGet as a priority over the Project?

When I clear the NuGet cache it gives me an error saying not all packages could be deleted, however when all my packages are gone this doesn't fix up the problem, it actually creates more issues.

I should note there's another project in this solution that also references Base.DLL but for the life of me I can't change it to not use a NuGet Reference either, this really feels like a bug.

The problem is it overrides my Project Reference. And yes, I've tried copying over the Debug folder DLL over the NuGet one locally but that still doesn't get me the pdb and symbolic debug info to debug into Base.

Visual Studio 2022 v17.5.4

2

There are 2 answers

2
PMF On

What I do to debug a nuget-library locally is the following:

  • Make sure my local version number is different from the last version on the nuget server.
  • Build the nuget file locally (using dotnet pack or the equivalent from whatever build system you use) and place it in some well-known folder, such as "artifacts".
  • Update the version reference in the consuming project.
  • In the consuming project/solution, open the Nuget explorer and add the "artifacts" folder as a local nuget source.
  • Build the consuming project. You should now be able to step into the library code (eventually, you'll need to disable the "just my code" option under Tools->Options->Debugging)

Of course, you can reference just a dll, but since there can be only one dll with the same name in the output folder, all references to the same dll (or their corresponding nuget) must be equivalent. Also, to avoid pitfalls in this case, you need to use the <HintPath> element in the project reference, or VS will just pick the first .dll that matches the given name:

    <Reference Include="..\Company.MS.base\bin\Debug\Company.MS.Base.dll">
      <Name>Company.MS</Name>
      <HintPath>..\Company.MS.base\bin\Debug\Company.MS.Base.dll</HintPath>
    </Reference>

This might work, but from my experience this should not be used anymore because it is prone to all kinds of problems (e.g. what if you're building Release?)

1
Jeremy Thompson On

So I found what was happening, the project.assets.json in the Obj folder contains all the NuGet Packages and removing the Base reference in this file solved the problem of NuGet overriding Debug Project References.

I settled on deleting all the Artifactory NuGets and the standard approach of conditionally loading DLLs:

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <ReferencePath>..\..\..\svc-base\src\bin\Debug\net6.0\</ReferencePath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
  </PropertyGroup>

  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <Reference Include="Company.MS.Base">
      <HintPath>$(ReferencePath)Company.MS.Base.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <PackageReference Include="Company.MS.Base" Version="2.1.12" />
  </ItemGroup>

TRICK: Say you have another project that also references the Base you can use this trick with your own tag for the ReferencePath, eg: ReferenceInfraHttpPath:

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <ReferenceInfraHttpPath>..\..\..\svc-infrastructure\src\bin\Debug\net6.0\</ReferenceInfraHttpPath>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
  </PropertyGroup>

  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <Reference Include="Company.MS.Infrastructure">
      <HintPath>$(ReferenceInfraHttpPath)Company.MS.Infrastructure.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <PackageReference Include="Company.MS.Infrastructure" Version="2.1.1" />
  </ItemGroup>