Nuget changes existing shared package reference to last package referenced - nuget

We are using an internal nuget server to handle a handful of common class libraries, and we manage our nuget packages at the solution level.
When a project (say MyProject) references a common library, say Newtonsoft.Json, the reference proprerly comes from C:\dev\myproject\packages\Newtonsoft.Json.9.0.1\lib\net461\Newtonsoft.Json.dll. The moment I add another package (say CommonProject) to MyProject that also references Newtonsoft.Json, the reference in MyProject CHANGES to C:\dev\myproject\packages\CommonProject\lib\net461\Newtonsoft.Json.dll.
This causes serious problems and a great deal of dll hell. The moment one of these common projects changes one of their references - let's say CommonProject no longer uses Newtonsoft.Json. The moment MyProject upgrades to the latest version of CommonProject, MyProject will now fail to compile because it can no longer find Newtonsoft.Json in C:\dev\myproject\packages\CommonProject\lib\net461\Newtonsoft.Json.dll. MyProject still lists Newtonsoft.Json as a nuget package reference, and the Newtonsoft dll is still sitting pretty in the Newtonsoft.Json folder of packages, but the dll reference is jacked up from when I first added the CommonProject nuget package. Nuget stupidly CHANGED every single shared package reference to map directly to the CommonProject folder instead of the packages folders for each of those packages. Even if the projects are referencing the exact same version of the same package, nuget still changes the reference.
Moving all shared package references to the folder of the last package added is making me think that nuget isn't managing packages at all.
Please tell me I'm doing something wrong, and let me know how I can get the packages to be properly referenced from their respective folders.

Related

Creating and installing a nuget package with referenced project

I want to publish a dotnetcore2.1 nuget package using dotnet pack and dotnet nuget push.
The package is a project in a solution that has a reference to another project in that solution.
I can't install the package because it can't resolve the referenced project.
I tried doing this, and it includes the referenced package .dll to the .nupkg file, but it's still not possible to install it.
I can't really figure out what is the 'expected' way to do this. I definitely don't intend to publish the referenced project to the nuget feed.
Is this a massive oversight by microsoft or am I not getting something?
You have a project A that you want to pack and this project references another project B that is not usable or not intended for use on its own, but from a design perspective it is reasonable to keep it separate for purposes like reuse. In the end the package for project A should also contain project B.
Indeed this is an issue tracked in the NuGet repository, issue 3891. In both this and your link to the corresponding .NET project issue there are some workaround involving MS Build, but there is no official support, yet.
As stated in the above issue, even Microsoft seems to be aware of this issue and simply creates packages for the referenced projects that are marked with
Please do not reference directly
I think that until project references are supported, the safest way is to do same, although it is not convenient. Workarounds may become obsolete or cause strange behavior. However, since your referenced project is only intended to be used in your main library, you could include it like this
<PackageReference Include="LLL.Client" Version="1.0.0" PrivateAssets="all"/>
This way, the package contents from your referenced project will only be included in your project and consumers of your main package will not be able to see them.

NuGet: Do Not Set Assembly Reference

I have created a nuget package containing a DLL that I want to share with multiple applications. I want to add this package to applications without setting a reference to the DLL. I am using dependency injection to load this DLL or a test DLL at run-time.
By default, nuget automatically sets a reference to all DLLs contained lib during installation.
Is there any way to configure the nuget package to not set a reference to the DLL when it is installed into my project?
Explicit assembly references. Although if your dll is loaded entirely at runtime (using MEF or Assembly.Load or something similar), then the build system might not copy the dll to the project's output directory. Note these docs are only correct for packages.config projects. I have a PR to improve the docs to explain how to do the equivalent thing for PackageReference.

Nuget dependency management (internal/private source)

I have my own Nuget package source for internal libraries. Some of the projects reference other projects in the same solution. Currently the dependencies are referenced to the Nuget package. Management of this be becoming a pain since if a project that has a dependency is updated, I have to wait for that dependency package to update so I can update the other project with the new reference. Some of the projects have multiple layers of dependency, so in some cases I to wait for 5 builds (build, update package, build, update package in next level, etc.) to get the package into the main project. Is there a better way to manage this or is this just the price to pay for using Nuget?
Ideally you wouldn't include your libraries in the solution for a given application and only add them to the solution via NuGet. You can manage versioning between the NuGet Packages in the packages.config file of a given library and by referencing NuGet Package versioning.
When I have a situation where I need to step through the library code from the consuming application then I remove the NuGet package and add the library project to the solution. Then add a project reference from the application to that library project. Ideally this should be a rare occurrence.

Why does NuGet store packages in C:\Users\<UserName>\.nuget\packages?

I understand that it is now possible to configure a global package directory for all projects but I noticed that NuGet also puts files in my home directory. Is it possible to configure a single repo which will be used for all projects?
NuGet introduced a new way of package management in for project.json (now deprecated) and PackageReference-based projects (default .NET Core, .NET Standard).
Instead of creating a solution-local packages folder to which all packages are downloaded and extracted (alt: repositoryPath location in NuGet.Config override), all packages are downloaded to a global location (controlled by globalPackagesFolder in NuGet.Config) which is defaulted to %userprofile%\.nuget\packages (~/.nuget/packages on linux/Mac).
The idea is that you don't have to download packages multiple times and the csproj files no longer reference all individual files but just the package. .NET Core projects also do not need to copy the NuGet packages' assets because the generated .runtimeconfig.json file specifies the location of the global cache to look up the packages at runtime, so builds can be a little bit faster.
See this question, I believe everything will be clear after that
Setting up a common nuget packages folder for all solutions when some projects are included in multiple solutions

Can a NuGet package declare a dependency without adding that dependency to the project?

I've created a NuGet package that contains some custom MSBuild tasks named MyCompany.MSBuild. These tasks have a dependency on Newtonsoft.Json. This means that after my package is installed in a project, Newtonsoft.Json.dll will have to be in the same directory as MyCompany.MSBuild.dll.
I could easily accomplish this by bundling my own copy of Newtonsoft.Json.dll in my package, but I wonder if there's a better way that means I won't have to update my package whenever a new version of Newtonsoft.Json comes out.
If I declare Newtonsoft.Json as a dependency, NuGet will install that package into the project when somebody installs my package, which isn't what I want to have happen.
How can I specify a dependency in my package without having NuGet install it and add project references? Additionally, how can I copy that package's assembly to my own package's folder after it is installed?
A package with a "hidden" dependency is something absolutely undesiderable in my opinion...
I know it's not a real answer but... Have you considered to use JavascriptSerializer instead of Newtonsoft.Json? It's a bit slower but your package will be absolutely self-contained: less pain for you and for your users.