Sharing packages.config across projects in a solution - visual-studio-2010

I am doing a code review. We have started using Nuget to import 3rd party libraries, for example Enterprise Library.
Previously we had the dll's for Enterprise Library on a share that was accessed by all projects in the solution. When it was updated it was updated for all projects.
Now it is controlled by the packages.config which is a file per project. A change would mean changing several files, with a chance that not all files that should have been updated were updated.
Is there a way to share packages.config across projects, or a way to be able to updated all packages.config at the same time?

In order to update packages in all the projects at the same time, you can launch the Manage NuGet Packages dialog at solution level (right click on the Solution).

Since you're doing a code review, allow me to say this: Enforcing package updates to its consumers is generally not a good practice.
Updating packages on the solution-level is the only way that ensures you the packages.config files will be updated as well (NuGet.exe update doesn't change these files).
packages.config files are project-related and can only be shared if all packages consumed by the projects are exactly the same. Add-as-link in the projects, update the repositories.config to point to the shared packages.config, and hope for the best (not sure whether NuGet checks for packages.config to be physically present in the project directory.
As you can see, this scenario is not mainstream and hence not supported in an optimal way.

Related

This project references NuGet packages that are missing on this computer (TFS)

I'm using TFS for the first time and attempting a build. I'm getting the error:
This project references NuGet package(s) that are missing on this computer. use NuGet Package Restore to download them.
I realize that there are many similar posts on StackOverflow and I've searched through quite a few of them. What I've gathered is that the two boxes under Package Restore in Package Manager Settings should be checked (but that this is also irrelevant now because they're checked by default). I verified that mine were both checked anyway.
The next piece of advice I considered is deleting the /packages folder from the Source Control version of my application. There is no packages folder there OR in my local (pre migration to TFS) version of the application. Instead, there's a ../packages/ folder (up one level) from the application folder. It seems that, at some point, I've opted to store the packages for all of my applications in the same folder? If so, where is this setting and what do I need to change it to either in my local version or in Source Control Explorer?
Thanks!

Difference between adding a Reference and adding a Nuget package to a project in Visual Studio

I have a VS (2015) project. I see there's a "References" section in the Solution Explorer view of my project that includes things like System.Core. I'm assuming these are .dlls that have been added to the project?
I can also right-click on the project file (again in the Solution Explorer) and select the option to "Manage NuGet Packages". I know the NuGet allows me to add external code to my project (e.g. external .dlls and associated files).
What's the difference between adding a reference to my project and adding a .nupkg to my project? Is it just that .nupkg can contain a whole bunch of other things aside from a .dll (e.g. documentation)? Why would I use one or the other?
What's the difference between adding a reference to my project and
adding a .nupkg to my project?
NuGet essentially does not differ from manually adding references, and ultimately adds references to the project. It is a tool that automatically adds assemblies to us and manages them, effectively improving the efficiency of our development projects.
For more details, you can check the document about nuget:
Put simply, a NuGet package is a single ZIP file with the .nupkg extension that contains compiled code (DLLs), other files related to that code, and a descriptive manifest that includes information like the package's version number. Developers with code to share create packages and publish them to a public or private host. Package consumers obtain those packages from suitable hosts, add them to their projects, and then call a package's functionality in their project code. NuGet itself then handles all of the intermediate details.
Because NuGet supports private hosts alongside the public nuget.org host, you can use NuGet packages to share code that's exclusive to an organization or a work group. You can also use NuGet packages as a convenient way to factor your own code for use in nothing but your own projects. In short, a NuGet package is a shareable unit of code, but does not require nor imply any particular means of sharing.
.
Is it just that .nupkg can contain a whole bunch of other things aside
from a .dll (e.g. documentation)?
Yes, NuGet package could include specify files in the package.
Why would I use one or the other?
Nuget provides several additional benefits:
it automatically configures your projects by adding references to the
necessary assemblies, creating and adding project files (e.g.
configuration), etc.
it provides package updates
it does all of this very conveniently
I'm sure that once you use it, you'll realize that it has many benefits.
Check Why use NuGet for more details.
Hope this helps.

Can NuGet use per-project package download paths within the same solution?

Consider this repo/file structure for our solution...
Shared Repo (Checked out to D:/Shared/trunk)
├───Shared1.dll Project
└───Shared2.dll Project
App1 Repo (Checked out to C:/Code/App1/Trunk)
├───App1 Project (Refs Shared1.dll project)
├───App1.dll Project (Refs Shared1.dll and Shared2.dll projects)
└───App1.sln
App2 Repo (Checked out to C:/Code/App2/Trunk)
├───App2 Project (Refs Shared1.dll project)
├───App2a.dll Project (Refs Shared1.dll and Shared2.dll projects)
├───App2b.dll Project (Refs Shared1.dll and App2a.dll projects)
└───App2.sln
To make working with the code easier, we bring in the Shared projects directly into the application's solutions, meaning for instance if you open App1.sln, this would be your project tree...
App1.sln
├───Shared1.dll Project
├───Shared2.dll Project
├───App1 Project (Refs Shared1.dll project)
└───App1.dll Project (Refs Shared1.dll and Shared2.dll projects)
As you can see, the two Shared DLLs are from a separate repository but are included in this solution. Visual Studio handles this without any issue, prompting you that you are updating multiple repos when you perform a commit against the solution. That's fine and is exactly what we want.
The issue we're having however is with NuGet. From what we understand, the NuGet.config (and the hierarchy/precedence of reading/applying them) is relative to the solution file, and therefore the projects' NuGet references are updated accordingly. This causes issues in that the references to the NuGet packages in Shared1.dll an Shared2.dll are relative to App1.sln when you're working in App1.sln, meaning if someone else is working in App2.sln and hasn't checked out their two trunks relative to each other exactly the same way you have, the references break.
Our work-around for this is to always check out all three trunks into the same folder as siblings, then put the packaging folder as another sibling, adding '../packages' in the NuGet.config next to each solution. This ensures the references never break, but forces the location of the checkouts which can be a problem.
C:/Code/
├───Shared Trunk
├───App1 Trunk
├───App2 Trunk
└───packages
However, if we could specify per-project package download locations, we could put the packaging folders relative to the projects themselves meaning it wouldn't matter where you check them out to. They would always find the packages they need. Yes, this means that in our example, there would be duplicate package downloads, but space on disk isn't the issue. Maintenance of the code is.
C:/Code/
├───Shared Trunk
│ └─sharedpackages
├───App1 Trunk
│ └─app1packages
└───App2 Trunk
└─app2packages
Again, what we want is when opening App1.sln, we want packages for Shared1.dll and Shared2.dll to go in 'sharedpackages' folder but packages used by App1 and App1.dll to go in app1packages.
So... is this possible? Can you specify different NuGet package download paths per project regardless of which solution they are in?
I'm in the same situation as /u/MarquelV.
From my investigation insofar into the options provided by nuget (at least up to ver. 3.5) for tackling this sort of scenario, I concluded that one has to completely ignore the graphical tools for nuget inside Visual Studio (at least as far as installing/restoring packages is concerned) and to also disable automatic package restore (Tools -> Options -> Nuget etc). Then resort to invoking nuget.exe from the command line whenever the need arises to install/restore packages specifying the folder in which the packages should be placed - this point is important because the graphical interfaces for nuget in visual studio are bend on storing packages in a "global" repository (typically right next to the .sln file of the solution).
In my projects I create an .nuget folder coupled with nuget.exe inside each and every project and reference dlls thusly.
Last but not least each and every project needs to restore packages by using nuget via the .csproj like so:
<Target Name="BeforeBuild">
<Exec Command=".\.nuget\nuget.exe restore .\packages.config -PackagesDirectory .\packages"/>
</Target>
The thing to take away from all this is that the graphical tools for nuget and the automatic package restoration (Tools -> Options -> Nuget) cannot be relied upon in order to achieve the goals described here.
I recently faced a similar issue. In my case I was combining projects from smaller solutions into a larger one. The projects were still referencing the packages in their subfolders, and I did not want to change those references and break the smaller solutions. I was able to solve it by symlinking the project packages path to the solution-level path.
mklink /J .\packages ..\packages
This effectively tricks the project into thinking it is using a more local version of packages when it was actually using the one from the larger solution.
It's not exactly the same situation, but close enough that I hope it can help someone.

Prevent solution relative nuget import from being generated in a project file?

I have problem with nuget packet management when using a shared project among different solutions which are located in different directories. One of the solution is using nuget, other one is not.
The problem is that the packet manager adds a line into .csproj file:
Now as the nuget packet management is only used among the shared project, a solution to the problem would be to change $(SolutionDir) to $(ProjectDir). This works and solves the problem for now.
Now whenever reopening the solution which has nuget packet management enabled, it automatically adds the same line (as shown on the picture above) into the shared project .csproj file, which again breaks loading the project from the other solution.
How to prevent the automatic generation of that import clause or is there any other elegant solution to the problem?
Enabling NuGet Package restore in the solution that doesn't use NuGet should fix your problem (right click the solution, enable package restore). While you aren't using NuGet in that project it doesn't really hurt to have that option turned on.
Personally I try never reference the same project from multiple solutions, and turn them into private NuGet packages instead. It can be a bit of a pain to development like this, as you need to create the new package, deploy then install it in your other project. But it solves many other headaches, like the one you're currently having and having developers accidentally break other projects when they check in.

Can WiX source refer to NuGet packages from another projects in solution?

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.

Resources