4
votes

I have a common library that I'm developing. Let's call it My.Common.

Version 1 of My.Common has been uploaded to my intranet Nuget server and is in use in several other libraries, such as My.Logging and My.Navigation.

While working on an .Net Core application that uses My.Common, My.Logging, and My.Navigation via Nuget, I've discovered a bug in My.Common. So I need to fix My.Common for Version 2. The bug affects a functionality used directly by the application - it has no effect on the other libraries, they can continue to use Version 1.

I open up the code for My.Common, attempt a fix, and compile. In the application, I removed the Nuget package for My.Common and add reference to the My.Common DLL in its bin folder.

Here is when I discover that I'm not seeing the changes to My.Common in my application. In the Properties window for My.Common, the path is showing as:

C:\Users\foo\.nuget\packages\my.common\1.0.0\lib\netcoreapp2.0\My.Common.dll

Here's how the reference looks in the .csproj:

  <ItemGroup>
    <Reference Include="My.Common">
      <HintPath>C:\Projects\My.Common\bin\Debug\netcoreapp2.0\My.Common.dll</HintPath>
    </Reference>
  </ItemGroup>

Even though I've added it as an assembly reference, it is being overridden and served from its Nuget package!

Since the assembly and Nuget package have different versions, I thought I could solve this by getting more explicit about the version.

  <ItemGroup>
    <Reference Include="My.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
      <HintPath>C:\Projects\My.Common\bin\Debug\netcoreapp2.0\My.Common.dll</HintPath>
      <SpecificVersion>true</SpecificVersion>
    </Reference>
  </ItemGroup>

When set to true, Visual Studio appears to be unable to find the assembly at all - Path is blank in Properties and the application fills with "(are you missing an assembly reference?)" errors.

It seems extreme that I would need to get local copies of My.Logging and My.Navigation, replace THEIR My.Common Nuget packages with assembly references, compile, and then replace all the Nuget packages in the original application with assembly references.

What can I do to get Visual Studio to actually use the local assembly reference?

2
I would create a pre-release package of version 2 of the library (something like 2.0.0-beta001) and use that, instead of trying to use the assembly reference. If its just a bug-fix, and there are no breaking changes, just update the 3rd number of the version (1.0.1-beta001)Bradley Uffner
I tried that, but it is very inconvenient for development. Every slight change requires changing the version number and installing the updated package into the application, and you cannot step the code like you can in a local assembly.friggle

2 Answers

3
votes

I've encountered this problem also, and the other answer suggested here was not viable in my scenario. From what I've seen, the references in package.assets.json will take precedence over any HintPath for the dll on your local system.

The package.assets.json file is generated in your solution's obj folder when NuGet packages get restored. From the docs here:

When the NuGet restore process runs prior to a build, it resolves dependencies first in memory, then writes the resulting graph to a file called project.assets.json in the obj folder of a project using PackageReference. MSBuild then reads this file and translates it into a set of folders where potential references can be found, and then adds them to the project tree in memory.

In my case I'd removed a NuGet reference to my library, added a reference to a local folder and verified the HintPath in my csproj file was pointing at it - something like this:

<Reference Include="MyLibrary">
  <HintPath>..\..\MyLibrary\bin\Debug\netstandard2.0\MyLibrary.dll</HintPath>
</Reference>

However, this file was still in package.assets.json, because one of the other NuGet packages my solution used was also referencing the copy of MyLibrary.dll in the local NuGet source. Because this reference was present, MsBuild was ignoring the HintPath for MyLibrary in my csproj, and taking the path provided in package.assets.json, used by the other NuGet package, instead.

What I had to do was remove the reference to the other NuGet package as well, and reference a local copy of it that had been rebuilt against the local copy of MyLibrary.dll. This way, nothing was using the MyLibrary.dll in NuGet. I also deleted package.assets.json for all the projects in the solution, and allowed NuGet to rebuild them from scratch.

EDIT: Working with VS2019 Preview 2.0, I'm seeing this behavior again, and the steps above didn't cut it this time. Fortunately, the version number of my local dll is different than the one in the NuGet source, so I edited the csproj files to specifically call out the version number of the local copy in the reference include. After doing so, VS picked up the right file:

<Reference Include="My.Annoying.Library, Version=1.0.6.0">
0
votes

Visual Studio 2017 using old Nuget package instead of assembly reference

You can use the project reference instead of using NuGet.

Just as you comment, if the referenced project is modified frequently, we have to rebuild it, re-create the nuget, re-publish it to the Nuget server for each modification and have to reinstall that nuget package to the referenced project. That will bring a lot of boring work. To resolve this disadvantages, the Project-to-project references should be a better way.

You can check the this thread for some more details.