We have a complex Visual Studio solution with projects referencing the same NuGet packages of different versions.
I feel this is a bad practice, as potentially can lead to dll hell
So - is there a way to control this?
Ideally it should be a part of either:
solution build
TFS gated check-in
delivery pipeline in whatever CI\CD tool is used.
I really liked Package Manager Console Powershell Reference. But I couldn't find a way to use those cmdlets (Get-Package and Get-Project -All) in external Powershell script outside of VS.
The simplest solution I see is to write a custom Powershell script, which reads .sln file, gets all the projects and for each of them reads packages.config and takes all nuget packages versions from there.
Or ... use a VS DTE to simplify this job, but so far I didn't have an experience of using it.
And then ... once we have this script - we can run it in CI.
Is there a simpler \ more standard way of doing this?
You should not worry about multiple components referencing different versions of packages. NuGet was built to cater for this scenario.
With DLL hell, you had no idea if A.DLL could work with a new version of B.DLL. But with NuGet the dependency is specified explicitly with a range of compatible version numbers.
The version resolution used by NuGet is to always pick the lowest version of a dependency that fits in the range.
Read here for details, it explains it well:
http://blog.davidebbo.com/2011/01/nuget-versioning-part-2-core-algorithm.html
At least as far as nuget is concerned, nuget can install different versions of packages in different projects. That said it's not advisable. As to which packages get restored it looks at the packages file (XML) anything in the file will get restored.
This file can get out of sync depending on how the package references were removed from the project/solution.
Related
Our team works on a project with TFS as source control. Sometimes that I want to check-in some errors happen.
D:\CustomManager.1.0.7184.35750\lib\net461\CustomManager.dll: Could not find a part of the path 'D:\CustomManager.1.0.7184.35750\lib\net461\CustomManager.dll'.
I gotta go to the Packages folder and make a new folder. after that, I have to copy the previous version of the package in that and then rename it to solve the case. This way is a little annoying because sometimes after that, new errors will show with different versions.
Additional information: This error will only be shown when I update the NuGet packages.
Is there a simple way to fix this?
Seems you directly checked libraries(dlls) in to TFS and manage version control of them.
It's not a recommend way, there are multiple downsides such as it's never exactly clear which projects are using which versions of which assemblies. It's a maintenance nightmare.
Suggest you use Nuget to handle these libraries in TFS. You should compile your code, package it in Nuget and publish it. For multiple projects you can upgrade their nuget references when appropriate, or stick with the older versions if they need to. If you need to reference a known-good, stable version, you just make sure your project is configured to pull a specific version from NuGet.
TFS use Package Management that hosts NuGet, npm, and Maven packages alongside all your other TFS assets: source code, builds, releases, etc, also be able to handle the external packages.
You could add external packages to a TFS Package Management feed. When you restore the packages, select the feed. All need packages will be restored entirely. To achieve this, just use Push NuGet packages to specify the packages you want to publish and the target feed location.
More details please refer Get started with NuGet Package Management in TFS
Update:
Keep looking for old packages, this will not happen if you already referred the latest dll in project. Please double check this part.
In your situation, if you want to check the dll in source control, you should add dlls in the solution/project and use relative path. Otherwise, tfs server may not find path.
For cache issue, suggest you to clear TFS cache then restart VS, and check in again, this may do the trick.
I'm trying to figure out a) if I'm going about this in the right way and b) how to update a solution level nuget package.
The core problem is that when a package is installed at the solution level (rather than in any particular project) and you try to update it, it doesn't remove the old reference. It just adds a new package reference, and imports both version. Which typically means (what with how powershell modules work) that the earlier powershell modules override the newer ones.
So what I have to do is uninstall the package and re-install it, which grabs the newer version. Seems inefficient.
Also, I can't seem to install or uninstall a solution level package from console. I have to do it with the Manage Nuget Packages utility, which I hate to use.
Here is some background on what I'm doing, if it helps:
I've set up a system at our company of using solution level nuget packages to add custom powershell script modules to the solution, as well as some more generalized scripted solutions I've written (like deleting TFS work items or changing a project name on the file system as well as within code).
So one project might have the DataServiceUtilities package and another would have the FrontEndUtilities package.
So, how can I update these packages without it adding two references? And can solution level operations be done in the Package Manager Console, which always defaults to targeting a project?
It appears that some of this comes from bugs in the Package Manager GUI tools, and Nuget in general
The Package Manager GUI tool doesn't handle updates properly for solution level packages. But if you run Update-Package from the package manager console it will correctly uninstall/re-install the solution-level package.
As for installing from command line, if a package has only a tools folder and no dependencies you can run install from command line and it sill install in the solution and ignore the default project.
However, as of now (Nuget 2.8) Nuget has a bug in it that causes it to treat solution-level packages with dependencies on other solution-level packages as project-level packages. It's apparently been in for about a year, and they claim it will be fixed in VS 2015. You can see the bug here: https://nuget.codeplex.com/workitem/3642
What this means is you cannot currently create a solution-level package with ANY dependencies. Please note that this is legal according to the documentation. Hopefully it will be fixed next year.
*Update
Just a quick update. It appears that in VS 2015 they have deprecated (or, more accurately, removed) solution level/tools only packages. After some out outcry they also decided to re-implement them in a future version, but it may be awhile before they do so.
Progress on re-implementing the feature can be found here: https://github.com/NuGet/Home/issues/1521
Discussion on how to work around the missing feature can be found here: https://github.com/NuGet/Home/issues/522
I was wondering about the right way to do this. For example, let's say you have a number of projects (part of a solution) that uses boost. Let's say you want to put the boost package in the solution so the entire thing is more portable.
How do you do that? Do you install boost in a directory within the solution? Can you reference it using relative directories, so it isn't portable?
Under Linux, for completeness, one could just store a tarball in the code under control, but it was left to the developer to bring it out and install it. I'm wondering how this is done (best practices) under visual studio.
[NOTE: I understand this might make the solution large, but the benefit would be a development environment that would run immediately without a bunch of package installs for each development system accessing the code.
In this case you could use the nuget package manager in visual studio to add the nuget boost package to your solution then boost will be available to the projects that need it. You can then enable package restore so that whenever the solution is built if the boost files are missing from the solution then nuget will restore them on build.
If you haven't already you will need to install the nuget package manager plugin for visual studio.
Where the package isn't available on nuget there are a number of options; you can build the package and then reference the assembly that's been built - you just store assemblies you need in a references directory. If your using source control software Svn or tfs possibly git ( I don't know) then you can store these in source control and then include them in the target solution via links. The final option I can think of is you can build the package into a nuget package and then store the result in your own private nuget store visual studio allows for this. Which solution works for you will depend on the size of the project, development team and the source control software you use.
We have a set of functionality that was previously in a regular dll file, but that is now in a Nuget package. Naturally, we want to pull it using Nuget instead of having to download and update the dll:s manually. All projects are handled in VS 2013, so we have access to it through the package manager.
Now, we need to go over all the projects in the source tree to update the reference to be a nuget reference instead of the old dll reference.
You can do this on a solution level using the package manager, but since there are several dozens of solutions and well over a hundred projects I'd rather not do it manually.
Is there a way to automate this? That is, to iterate through the source tree, find every .sln file and update the references in its underlying project files?
You can probably do it by writing a small C# program. Install NuGet.Core and NuGet.VisualStudio package to the program to use functions in nuget.core.dll and nuget.visualstudio.dll, plus some DTE functions.
I have a solution with two projects:
.NET application
WiX setup project.
I know, that it is possible to refer to project output in WiX source ($(var.WindowsFormsApplication1.TargetFileName)).
Now I've added a NuGet package reference to my .NET application. So, I want to bring NuGet package content into my setup.
Is there any way to do this instead of adding files manually?
I don't believe there is any linkage. I know what nuget is but I haven't used it much because it's more about brining your .NET dependencies into scope then software distribution. Depending on how nuget lays the files down you might be able to do something like $(var.SomeProject.TargetDir)nuget_fetched.dll.
This is assuming that SomeProject uses nuget in such a way that the references are copied locally and available in the Outdir of the project.
I wrote a Resharper live template to cut out a lot of the typing involved in adding the files, but essentially I've just added the files manually. Creating a Wix component per nuget package keep things neat.