Where does Visual Studio is referring the actual NuGet referenced DLL? - visual-studio

I've added Autofac library using NuGet and I see it in my references as shown below.
But when I check the properties [F4] of Autofac by clicking on it, it shows empty property box in Visual Studio.
Also, I don't see Autofac folder under packages folder.
I see only Package reference in .csproj file. Then how does it locates the DLL? Where is the actual DLL? I see it's automatically coming inside BIN. How does it come?
Main Issue: Locally I'm able to build the solution but same solution fails on TFS build agents. It's unable to find the NuGet reference. So where can I find DLL references? or how to push it to TFS?

As #magicandre1981 already explained, with PackageReference style package referencing (as apposed to package.config-style, also see this for more background on the differences, in case you didn't know), the packages are not located in a per-solution packages-folder, but in a central one (by default %USERPROFILE%\.nuget\packages). Albeit you can easily change the location using the NUGET_PACKAGES environment variable (which also works as a TFS Build variable, because they are provided as environment variables to build steps).
Furthermore, inside Visual Studio you see no path, because the actual path to the DLL is determined at build time. You can see part of that path in your <project-dir>\obj\project.assets.json file (which is generated during the restore target/operation), but the full path you will only see in the MSBuild logs (for example when actually calling the csc.exe executable/C# compiler or during ResolveAssembyReferences-task).
Note that for .NET Core, i.e. "SDK style" projects, the path is actually shown in properties (as are the actual DLLs in a node underneath the "package" node.
One can only assume that the integration of PackageReference in "old" projects is not fully done yet (if ever).
For comparison a PackageReference in an "old" / non-SDK-style project:

You use the new Package Reference where the NuGet files get get stored into a cache:
Solution-local packages folders are no longer used – Packages are now
resolved against the user’s cache at %userdata%\.nuget, rather than
a solution specific packages folder. This makes PackageReference
perform faster and consume less disk space by using a shared folder of
packages on your workstation.

Assume you are using TFS 2015, the NuGet Restore task name should be NuGet Installer which under Package when you add tasks.
So, if you have installed Nuget in the build machine, then you can use the task directly.
You can also custom nuget.exe for TFS 2015 build -- Just specify the Path to NuGet.exe
You can refer to Mummy's blog- Custom nuget.exe for TFS 2015 build for details.

Add a NuGet Restore task to your build so that the packages are restored.

Related

Azure Devops - Interop Libraries

Currently through Azure Devops, I'm setting up a .Net Desktop type with pipe-line that includes assembly libraries. In my understanding this should've work if the scenario was TFS is on-premise and I can just install any 3rd party non-nuget libraries in that server and make the build work. Right now I was able to make this work by literally copying the .dlls but I felt its more of a hack than actually letting the build know that I'm referencing assembly / non-nuget package libraries.
I'm pretty sure i've missed something, is there a way to properly set this up?
Even though it's not a recommend way, but you could check in these libraries/dlls in source control. TFS could download them from server to your build agent and refer them.
First, make sure your local build is successful and if just the TFS build is failing then it is usually due to dll reference path issue. Make sure that the Dll is referenced as a relative path in the project file (.csproj).
To add a relative reference in a separate directory, such as C:\tfs_get\Sources\assembly\abc.dll, do the following:
Add the reference in Visual Studio by right clicking the project in Solution Explorer and selecting Add Reference.
Find the *.csproj where this reference exist and open it in a text editor. Lets say your .csproj location is c:\tfs_get\sources\myfolder\myproject\myproj.csproj
Edit the < HintPath > to be equal to
..\\..\assembly\abc.dll
This build will work properly with the assumption that the folders ( assembly, myfolder) under the sources folder exist in TFS.
Update
Have a folder named "libs", or "libraries", for example, that contains all the assemblies required by your projects to compile and run.
Reference these assembly by right click the reference folder of project and browser to these assemblies files.
For build, in Source Settings (XAML, Build Agent Folder)/Repository, keep the similar structure.
More details please take a look at this similar question : How to properly check in DLLs/assemblies to TFS/Visual Studio Team Services (was VSO)

How to use a custom version of one DLL otherwise found in via referenced NuGet package?

Cross platform Xamarin Forms project in Visual Studio and Visual Studio for Mac. The project references Akavache. Akavache has a dependency of akavache.sqlite3. I have made a custom change to a DLL in the akavache.sqlite3 repo and built the DLL locally, and would prefer not to have to switch the whole Akavache package tree over to a custom build for all the Akavache dlls and dependencies. So essentially...would like to continue referencing the NuGet package like normal but "substitute" one DLL on the fly. Or something equivalent like that!
But it needs to be portable too. At first I used a post build copy command to overwrite the "standard" dll that gets put in the TargetDir. That works in the sense that it copies to TargetDir, but for Android copying the DLL into the TargetDir does no good. The DLL is already incorporated into the APK in the TargetDir instead. So it would need to happen some other way. Same basic issue if you used MSBuild instead of a post build command line.
Any thoughts?
FWIW, my current workaround is to copy the DLL over top of the cached NuGet package location. But the problem with this approach is anytime the cache would get cleared/updated it needs to be reapplied. That's also not an obvious step to do, or easily automated, when another developer want to get set up on their machine.
Any .nupkg files are just ZIP files with some metadata, so you can change at the contents. The NuGet Package Explorer should make it a little easier to view the contents.
The NuGet Gallery (e.g. https://www.nuget.org/) has a "Download" link on the left hand side, otherwise just install the package into an empty project and then take a peek.

Nuget Automatic Package Restore not working on project (.csproj) build (without solution)

We have a solution which contains several projects. Some projects have NuGet packages installed, for example Json.NET. The whole solution is checked in to TFS Version Control, without the packages folder. We have set up Automatic Package Restore according to the "Nuget 2.7+ method" as described in the Nuget documentation (actually we didn't set up that much since all this is enabled by default).
When we build this solution on another computer, all packages are getting restored.
When we build this solution on our TFS 2013 Build server, all packages are also getting restored.
Now here comes the problem:
When we create a build on our TFS 2013 Build Server which should build only one of the projects in the solution (so targeting the .csproj file instead of the .sln file) the nuget packages are NOT getting restored!
Can anyone tell me why this is happening, or tell me if this is by design? I really don't want to build the whole solution, since it is a release build for only a single small project, but i do want the packages getting restored automaticly...
I believe the Automatic Package Restore hooks into the Build Solution event. Since there's no solution, it's not triggering the restore.
To build a single project, you may need to create a new solution that references just that project.

How do I reference instead of copy js files from a Nuget package at build time in TeamCity?

I've got a packages.config file checked into source control. This specifies the exact version of the Nuget dependency I want. We have our own NuGet repository. We are creating these NuGet packages ourselves.
<packages>
<package id="Dome" version="1.0.0.19" targetFramework="net45" />
<package id="Dome.Dojo" version="1.0.0.19" targetFramework="net45" />
</packages>
These packages have some JavaScript files which when you add the Nuget package as a reference in Visual Studio are copied to the Scripts folder in the project.
I don't want to check these JS files in to source control, I just want to check in the packages.config file.
When my project builds in Team City (or when I build in Visual Studio after a fresh checkout) it doesn't copy the JS files from the NuGet package. There's a question here explaining a similar problem:
NuGet package files not being copied to project content during build
But, the solution in the answer to that question doesn't work for me; that solution uses ReInstall, which is problematic because it can automatically upgrade the version in the packages.config file (say if a dependency is specified as a >=).
The whole point of this is that I want to be able to checkout a revision from my source control, and build that version with the right dependencies AND I want to use the nice packaging features of NuGet. So, I don't want any "automatically update to the latest version during the build."
There's an issue against NuGet (http://nuget.codeplex.com/workitem/2094) about NuGet files not restoring content files. And it's Marked as Closed By Design.
Thinking about how this works a little more, it appears to me (but I'm not 100% sure) that for assemblies NuGet has a different behaviour - it doesn't copy them into the project, instead it references them from the location in the packages folder. It strikes me that js files in the NuGet package should be referenced analogous to how dlls are referenced.
Is there a way to construct a NuGet package so that it references the JS as links in the project (in a similar way to how you can add an existing File as a Link in VS)? And would this solve my problem?
If not then I'll take the advice given by Jeff Handley when closing ticked Nuget Issue 2094 mentioned above:
The option you'd have is to create a new console executable that
references NuGet.Core, and you could build a supplemental package
restore for your own use that copies package contents into the
project.
Writing my own command line tool to copy the contents does seem like I'm pushing water uphill here - am I doing something fundamentally wrong?
The underlying problem here is Visual Studio's relatively poor support of JavaScript projects and JavaScript's lack of built-in module loader.
For C#, when you install a package it adds a reference in your .csproj file to the assembly on disk. When you build, MSBuild knows to copy the thing referenced to the bin directory. Since you aren't checking in your bin directory, this all works great.
Unfortunately for JavaScript, the build system isn't nearly as matured and there aren't well defined guidelines for NuGet to follow. Ideally (IMO), Visual Studio would not run web sites directly from your source directory. Instead, when you built it would copy the JavaScript files, CSS and HTML files to a bin directory from which they would be executed. When debugging, it would map those back to the original JavaScript or TypeScript files (so if you make a change it isn't to a transient file). If that were to happen then there is now a well-defined build step and presumably a well-defined tag for JavaScript files (rather than just "content"). This means that NuGet would be able to leverage that well-defined MSBuild tag and package authors could leverage the NuGet feature to do the right thing.
Unfortunately, none of the above is true. JavaScript files are run in-place, If you did copy them to bin on build Visual Studio would do the wrong thing and editing from a debugger would edit the transient files (not the originals). NuGet therefore has no well-defined place to put files so it leaves the decision up to the package author. Package authors know that the average user is just going to be running directly from source (no build-step) so they dump files into the source folder where they must be checked in to version control.
The entire system is very archaic if you are coming from a modern ecosystem like C# where someone took time to think these things through a bit.
What you could do is create an MSBuild task that, before build, would go through all of your packages, look for content, and copy that content to the desired location. This wouldn't be terribly difficult, though would take a bit of work.
Also, package authors could include a build-task that does this in their package so that before-build all of their content was copied local. Unfortunately, if only some package authors do this then you end up with weird fragmentation where some packages need to be committed to version control and others do not.
When a package is installed into a project, NuGet in fact performs these operations,
Download the package file from source;
Install the package into the so called packages folder, which is $(SolutionDir)\packages by default;
Install the package into the project, which consists of adding references to DLLs, copying content files into the project directory etc.
When a package is restored, only the first two steps are executed. Projects will not be touched by nuget package restore. Which is why the js files in your project will not be "restored".
The only solution for now is to check in the js files in your project.
If you are the owner of the package then you could use the nuget package i've created to be able to have a folder called "Linked" in the package and have a simple Install.ps1 and Uninstall.ps1 (one liners) to add every file in the nuget package's linked folder as existing to the project.
https://github.com/baseclass/Contrib.Nuget#baseclasscontribnugetlinked
I didn't try out how publication treats linked files, the problem is debugging the Project, as the JavaScript files will be missing in the directories.
If you are using git as source control you could try my nuget package which ignores all the nuget content files and automatically restores them before building.
Step by step example in my blog: http://www.baseclass.ch/blog/Lists/Beitraege/Post.aspx?ID=9&mobile=0

Should .nuget folder be added to version control?

With newer versions of NuGet it is possible to configure a project to automatically restore NuGet packages so that the packages folder doesn't need to be included in the source code repository. Good.
However, this command adds a new .nuget folder and there is a binary there, NuGet.exe. This can also be re-created automatically by Visual Studio and so it doesn't feel correct to add that to version control. However, without this folder Visual Studio won't even load the solution properly.
How do you people deal with this? Add .nuget to source control? Run some command line script before opening the solution?
This post is old, you should not be using solution level NuGet package restore anymore. As of version 2.7+ there is an option in the NuGet setup to automatically restore packages on build.
So the .nuget folder can be deleted and the option removed from your projects.
http://docs.nuget.org/docs/reference/package-restore
UPDATE: With the release of NuGet 4.x and .NET Standard 2.0, when you use the new csproj format you can now use package references, ironically reintroducing the dependency on msbuild to restore packages, but now packages are a first class citizen of msbuild. The link above also makes mention of the PackageReference, but the following announcement details it better:
https://blog.nuget.org/20170316/NuGet-now-fully-integrated-into-MSBuild.html
And the NuGet 4.x RTM announcement, which ironically isn't as useful:
https://blog.nuget.org/20170308/Announcing-NuGet-4.0-RTM.html
UPDATE 2: Apparently with VS2017 you can even use package references with classic csproj projects, but they aren't backwards compatible anymore, and there have been some problems with restoring package sub-dependencies. I'm sure that will all be resolved.
#Richard Szalay's answer is right - you don't need to commit nuget.exe. If for some reasons Visual Studio does not automatically download the nuget.exe, make sure you have the following set to true in the nuget.targets file:
<!-- Download NuGet.exe if it does not already exist -->
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
Close the VS solution, reopen it and build it. Visual Studio should download nuget.exe automatically now.
According to this thread, the .nuget folder should be version controlled.
You need to commit .nuget\nuget.targets, but not nuget.exe. The targets will download the exe if it doesn't exist, as long as you change DownloadNuGetExe to true in nuget.targets
Although I usually don't like the idea of adding exe's to source control, I would suggest that source control should contain anything that is required in order to open, build and execute the project.
In this case it sounds like the .nuget folder is a required dependency. Therefore it ought to be under source control.
The only question left, that you need to research, is how NuGet is going to react if that folder is marked read-only, which TFS will do once it has been checked in.
Update:
I did a little more research on this as I've never used NuGet before. http://blog.davidebbo.com/2011/03/using-nuget-without-committing-packages.html
I would suggest that probably what you want to do is make NuGet a requirement that has to be installed on every developers workstation.
Further, you should place in source control the batch file required to get a workstation ready to start editing the project. The batch file is going to run the commands necessary to get and install the dependency packages.
Beyond that I'd say you might want to contact NuGet directly to ask them how, exactly, this is supposed to work.
Now that nuget supports package restoration we're looking at it more closely.
We use Subversion for source control, and my initial thoughts are that .nuget should be added to our repository, but added using svn:externals so that it points to a single location.
That way we can automatically push out new versions to all developers and projects. For projects on release branches, rather than HEAD, we can specify the revision of svn:externals reference if we want to leave nuget alone.
We have a lot of projects, so it also means not duplicating nuget.exe multiple times in the repo.
We have the nuget.config file in the folder, as it has the references to our internal Nuget server, using the Package Sources area:
https://docs.nuget.org/consume/nuget-config-settings
Apart from this reason, you should let Visual Studio handle the downloading of packages.

Resources