Mormegil
Mormegil

Reputation: 8071

dotnet restore keeps using local project instead of nuget package

I have a .NET-core project in Visual Studio 2015. In it, I used a Nuget package, but after finding a bug in the package, I checked out its source code and included the library project into my solution to debug the issue. After successfully resolving the problem I sent the fix upstream, it was accepted and a new Nuget package version was released. So I went, removed the library project from my solution and intended to update the package to the fixed version to continue working on my project. Visual Studio Nuget Package Manager found the new version and everything seemed fine for a while.

However, it did not work. Every time I try to update or reinstall the package, the library project reappears in my solution instead of just going to the nuget package dependencies. (Obviously, it still contains my checked-out version instead of the current nuget package version, so the NU1007 warning appears – dependency specified was different than what it ended up with.)

I have deleted all user/temporary files in the project, I have deleted the project.lock.json file. Using a global file search, there is not a single appearance of the file path to the library project (its source code was checked out outside the main project’s directory) in any file under my project’s directory. Then I run dotnet restore, it does not say anything interesting, but it creates the project.lock.json file, and inside, it adds the old version of the package as "type": "project" with path going to its project.json and msbuildProject going to its xproj files in a completely different directory.

Where does dotnet remember/find the path? Should it be doing this? What can I do to stop it from doing this and instead start using standard Nuget package source again?

Upvotes: 2

Views: 2169

Answers (2)

Svek
Svek

Reputation: 12858

You must place the solutions into separate directories as .NET Core Projects in VS2015 has unique file system requirements, and will behave poorly when you put them in the same directory (each solution will generate a hidden .vs folder, and they will end up overlapping).

For example you could change the directory structure to this:

.\Solutions\A\ <-- Directory for Solution A
.\Solutions\B\ <-- Directory for Solution B
.\A\ <-- Project A
.\B\ <-- Project B

This would mean that the hidden .vs folders for each solution will no longer overlap (ie, the solutions do not share this)

.\Solutions\A\ProjectA.sln
.\Solutions\A\global.json
.\Solutions\A\.vs\

.\Solutions\B\ProjectB.sln
.\Solutions\B\global.json
.\Solutions\B\.vs\

You can get additional information with this article: Organizing Your Project to Support .NET Framework and .NET Core which contains an additional note:

Renaming project.json to {project-name}.project.json

  • This prevents potential conflict in Visual Studio when trying to restore packages for the libraries in the same directory. For more
    information, see the NuGet FAQ under "I have multiple projects in the same folder, how can I use separate packages.config or project.json
    files for each project?
    ".
  • Alternative: Create the PCL in another folder and reference the original source code to avoid this issue. Placing the PCL in another
    folder has an added benefit that users who do not have Visual Studio
    2015 can still work on the older projects without loading the new
    solution

Additional Information

In addition, you might want to read more about the .NET Core Tooling in Visual Studio

csproj Format

The csproj file format has been significantly simplified to make it more friendly for the command line experience. If you are familiar with project.json, you can see that it contains very similar information. It also supports a wildcard syntax, to avoid the need of listing individual source files.

This is the default csproj that dotnet new creates. It provides you with access to all of the assemblies that are part of the .NET Core runtime install, such as System.Collections. It also provides access to all of the tools and targets that comes with the .NET Core SDK.

<Project>
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="**\*.cs" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NETCore.App" Version="1.0.0" />
    <PackageReference Include="Microsoft.NET.SDK" Version="1.0.0" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

As you can see, the resulting project file definition is in fact quite simple, avoiding the use of complex values such as GUIDs. A detailed mapping of project.json to .csproj elements is listed here.

Because the improved .csproj file supports wildcards, you don’t require the full listing of code files in the project file. This enables a great tooling experience: Files added to the folder will automatically show up in the Solution Explorer. Changes made in files will automatically modify the project file if needed.

enter image description here

NuGet Package references

You can add NuGet package references within the csproj format, instead of needing to specify them in a separate file with a special format. NuGet package references take the following form:

.

For example, if you want to add a reference in the project above to WindowsAzure.Storage you just need to add the following line to the other two package references:

  <ItemGroup>
    <PackageReference Include="Microsoft.NETCore.App" Version="1.0.0" />
    <PackageReference Include="Microsoft.NET.SDK" Version="1.0.0" />
    <PackageReference Include="WindowsAzure.Storage" Version="7.2.1" />
  </ItemGroup>

Upvotes: 1

Micka&#235;l Derriey
Micka&#235;l Derriey

Reputation: 13704

Note: This answer has been copied from here

Local projects take precedence over NuGet packages. I don't know at what level this is baked-in, though.

The solution is to explicitly specify in your project.json that you want to reference a NuGet package and not the project in the same solution.

"YourNuGetPackageName": {
    "type": "package",
    "version": "VersionOfYourNuGetPackage"
}

You can have a look at an example here.

Upvotes: 0

Related Questions