How to deal with relative HintPath for Nuget dependency assemblies? - visual-studio

This issue describes in more detail and discusses the problem I was describing in a recent question - a project was in multiple solutions and the <HintPath> was to a local packages directory. So depending which solution was being built, it ran into dependency confusion issues.
Does anyone know of a good workaround? It can't be unusual to have the same project in multiple solutions and it seems crazy that Nuget, which is supposed to help avoid dependency hell, is relying on fragile local paths.

Does anyone know of a good workaround? It can't be unusual to have the
same project in multiple solutions and it seems crazy that Nuget,
which is supposed to help avoid dependency hell, is relying on fragile
local paths.
I think you could change the repositoryPath path in nuget.config file so that the hintpath will uses packages under the global nuget caches rather than copy the packages again under your solution folder. This relieves nuget package dependency.
Open C:\Users\xxx(current user name)\AppData\Roaming\NuGet\NuGet.Config and then add these in it:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="%USERPROFILE%\.nuget\packages" />
</config>
</configuration>
Then restart VS and it will reference the packages directly from the global nuget caches.
Then run update-pacakges -reinstall under Tools-->Nuget Package Manager-->Package Manager Console to uses the new Hintpath.
Besides, use PackageReference nuget management format will avoid this behavior and you will not bother by the complex Hintpath problems. It is a new nuget package management format and much easier.
Right-click on the packages.config file--> migrate packages.config to PackageReference.
And Note that when you migrate into Build Server, and if you only build it by command line, you should run nuget restore xxx.sln to restore these packages. See this link.

Related

DLL version clashes in different NuGet packages

In my solution some projects reference the "MahApps" NuGet package, which includes 'System.Windows.Interactivity.dll' 4.5.0.0. Some projects also reference the "Prism" NuGet package, which includes 'System.Windows.Interactivity.dll' 4.0.0.0.
The app.config has a binding redirect of "0.0.0.0-4.5.0.0" to "4.5.0.0" by the way.
A handful of projects reference both NuGet packages, and looking in their "References" lists some of them have S.W.I v4.5.0.0 while others have v4.0.0.0. (I'm guessing this randomness is down to the order in which the packages were installed to the projects).
Sometimes the solution will build and run fine, but if only make a code change in one of the projects referencing S.W.I 4.0.0.0 then I get a runtime error along the lines of "v4.5.0.0 could not be found". v4.0.0.0 is being copied to the build output folder but my binding redirect is telling it to expect 4.5.0.0.
Any thoughts on a solution? I could try uninstalling and reinstalling the packages in the projects causing the issue, to see if I can get them to reference the 4.5.0.0 in the MahApps package, but my concern is that this may not be guaranteed to work during a package restore, screwing it up for another developer (or the build server).
I ended up upgrading to Prism 6, which includes no DLLs other than its own. Thankfully it was a straightforward job.
I also had to remove the MahApps package then add it again, to get Visual Studio to add that package's System.Windows.Interactivity.dll (4.5.0.0).

Reference nuget package project from another nuget package project in same solution

I am creating couple of .NET Standard 1.6 libraries that I want to publish as Nuget packages. They share a common libary that is a 3rd project in the same solution as the first two. The shared library has no value by itself, but I am assuming that if I want people to use both of these two libaries in the same project I should publish the shared library as a Nuget package as well. If I don't I am worried about multiple copies of the same shared library "colliding" or not properly warning when there are version mismatch issues.
Am I correct that the shared library needs to be a Nuget package as well? Is there a way to reference the shared library as Nuget package, but use is as if it was a project reference when developing / debugging the 2 main libraries in this solution? If I had to publish to Nuget.org and wait for the package be propagate through the Nuget.org system before using a changed version in a debug session that is REALLY going to slow down development. Note that these are .NET Standard projects. I found How to reference related projects in the same solution when Nuget packages are the required output but that doesn't seem to work with .NET Standard (getting errors during pack) and I am also not sure if .NET Standard not using nuspec files anymore also would cause a problem.
I am also not sure if .NET Standard not using nuspec files anymore also would cause a problem.
The .NET Standard still using .nuspec files, and using old school nuget pack and a .nuspec will resolve this issue.
As per document dotnet pack:
NuGet dependencies of the packed project are added to the .nuspec
file, so they're properly resolved when the package is installed.
Project-to-project references aren't packaged inside the project.
Currently, you must have a package per project if you have
project-to-project dependencies.
So, to include project-to-project references in NuGet packages, you need manually maintain a .nuspec file and add dependencies. You can refer to the Create .NET Standard packages with Visual Studio 2015 for detail info.
Besides, dasMulli has provided a simpler way to do this by involving adding and hooking up a custom target :
<Project>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeP2PAssets</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\testprivatelib\testprivatelib.csproj" PrivateAssets="All" />
</ItemGroup>
<Target Name="IncludeP2PAssets">
<ItemGroup>
<BuildOutputInPackage Include="$(OutputPath)\testprivatelib.dll" />
</ItemGroup>
</Target>
</Project>
The source code comes from: "donet pack" is not including project references

NuGet newbie mayhem

I'm really new to NuGet and having all kinds of trouble with it. So the latest problem is that I generated a bunch of .nupkg files and put them in a shared folder on the network and then set NuGet up to look there for updates. So let's say in the folder I have:
Author.library.2.1.0.nupkg
Author.library.2.2.0.nupkg
Author.library.2.2.1.nupkg
I then found out that the target framework (.net) is different for some of my projects (under the same solution), so I generated new packages for each target:
Author.library.net40.2.1.0.nupkg
Author.library.net40.2.2.0.nupkg
Author.library.net40.2.2.1.nupkg
Author.library.net45.2.1.0.nupkg
Author.library.net45.2.2.0.nupkg
Author.library.net45.2.2.1.nupkg
Next I right-clicked on the solution and chose Manage NuGet Packages for Solution and then went to Online, pointed to the Installed Packages and was able to install each package to the applicable projects (.csproj files). But now when I open the NuGet Package Manager for the solution and click on Installed Packages, all I see is once instance of library. If I click on it, on the right I can see that it's pointing to the Author.library.net45 package, but I have no way of seeing the .net40 version of the library. So I can't add it to the .40 projects.
And lastly, what if I want some of the projects to point at an older version of a package. I know that I am suppose to be able to specify that in the packages.config file:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Author.Library" version="2.2.0" allowedVersions="
[2.0.0,2.3.0)" targetFramework="net45" />
</packages>
which should load anything above (and including) 2.0 through 2.3)
or
<package id="Author.Library" version="(,2.4.0" targetFramework="net45" />
which should load any version below 2.4.
So my main question is why can't I see the two versions of the package in the NuGet Package Manager? And also, how do I best limit the versions that will apply to a particular library.
It looks like you cannot see the different packages since they both have the same package id of Author.Library. This is based on what you have shown in your packages.config file.
Also I would not have separate NuGet packages just for assemblies that target different frameworks. Instead put them in a single NuGet package in their own lib directory (e.g. lib/net40 lib/net45). You can have multiple assemblies targeting different frameworks in the same NuGet package. NuGet will pick the best match when installing the NuGet package into the project. Also note that you can use a NuGet package that contains just .NET 4.0 assemblies with a .NET 4.5 project since the assembly is compatible.
The allowedVersions attribute in the packages.config file is the thing to use if you want to restrict the NuGet packages that a project can update to.

Hint Path is messing up Nuget Restore

I've got 3 projects in my solution; Api, Tests and Tests.Acceptance. When I bring the solution down from Git the Test and Test.Acceptance files fail to restore.
I've tried adding a .nuget\NuGet.config\ with the following code
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="C:\packages" />
</config>
</configuration>
And while that seems to pull the packages into that folder the actual solutions themselves are not heeding the config.
I have not run a Update-Package -reinstall on the project, is this a necessary step in getting the csproj files to obey the new NuGet.config?
You are right that the HintPath will confuse other users when cloning a project in a few scenarios like an absolute repository path that is specified in a user's nuget config that is not overridden by the project. As long as everyone uses the same repositoryPath - either through a global config or a NuGet.Config file in the solution folder -, this shouldn't be a problem.
If you want to support a wide variety of these configs, I suggest moving off packages.config and use the new PackageReference nuget mechanism in VS 2017 / NuGet 4 where the csproj file itself lists the packages it needs and does not contain any hint paths. Furthermore, a global package cache will be used for all projects. Refer to NuGet's blog post on the integration, especially the section What about other project types that are not .NET Core? (Note that the mechanism is fully supported in the currently released VS 2017 version)

How to keep VS2015 NuGet from adding packages to TFS

VS2013 had a bug where NuGet would add packages as pending changes, even if you told it not to with .tfignore. There was a workaround, but it doesn't work with VS2015/NuGet3, and NuGet is back to its old tricks. Is there a "Nu" workaround? :-)
Microsoft Connect item: NuGet adds packages to TFS despite .tfignore
It looks like this is fixed in version 3.2 RC of the NuGet Visual Studio 2015 Extension - updating to this version worked for me, at least.
A discussion about this issue can be found here where it is recommended to update from NuGet 3.1 to 3.2 RC.
Update
Version 3.2 of the extension has now been released (found here) which includes this fix.
Clarification
To get this working you need two things:
A nuget.config file containing the disableSourceControlIntegration setting
A version of the NuGet Visual Studio 2015 Extension that respects the disableSourceControlIntegration setting (versions from 3.2 onward should work)
As indicated in the docs:
NuGet first loads NuGet.config from the default location, then loads any file named NuGet.config starting from the root of the current drive and ending in the current directory.
This means that you can specify <solution><add key="disableSourceControlIntegration" value="true" /></solution> in the default config file for your user profile (found at %APPDATA%\NuGet\NuGet.Config) or in the NuGet config file in your solution directory, e.g., \MySolution\.NuGet\NuGet.config.
In your %AppData%\NuGet\NuGet.Config file, add the following just before the </configuration> XML tag...
<config>
<add key="repositoryPath" value="C:\NuGetPackages" />
</config>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
...you can specify any path you want - the important thing is putting it OUTSIDE your TFS workspace!
Now you never have to worry about that stuff again. Your solution folder will not contain any packages anymore; all solutions will default to using your custom packages location instead.
NOTE - This works is on a per-user basis.
Until now, I've been doing the same in a one-config-per-solution (\.nuget\NuGet.Config) manner. Thanks to #dsghi for the insight!
Make sure your solution folder does not contain a .nuget folder (old way of doing things). Even if the folder is NOT included in the solution and only in the file system, it will override everything!
I have the same problem and I haven't found a real solution yet.
The only workaround I've found so far is:
Right click the packages folder in "Team Explorer - Pending Changes"
and select "undo".

Resources