How does VS 2017 determine .NET Standard dependencies from Paket? - visual-studio

I have a proof-of-concept solution that has a .NET Standard project in it. I use Paket to manage my nuget dependencies. I am able to use paket add and dotnet restore, per these instructions, to add a nuget dependency to that project. When I reopen my solution, I see that a paket.references file has been added to that project, and that a "NuGet" section has been added under the project's "Dependencies" section in "Solution Explorer".
I'm curious, how does VS2017 know what dependencies to list that "NuGet" section?
From the instructions I linked to above:
In contrast to traditional .NET projects Paket will not add assembly
references to your project files. Instead it will only generate a
single line:
<Import Project="..\..\.paket\Paket.Restore.targets" />
This hook tells the .NET SDK to restore packages via Paket's restore
mechanism. A nice benefit is that your project files are now much
cleaner and don't contain many assembly references.
I'm sure I'm missing something, but I don't see anything in Paket.Restore.targets that would tell Visual Studio where to look to find the dependency chain of the nuget package I added to the project. There are no direct references to any dependencies mentioned in the project file.
For context, I have a repo where I'm trying to add a .NET Standard project to a solution that is full of .NET Framework projects. I'm running into an issue where paket add seems to correctly create a paket.references file for the new project, but dotnet restore doesn't seem to be causing the project references to update, resulting in my project not having a reference to the nuget dependency I'm trying to have it reference. I'm having trouble creating a reproducible example (my proof-of-concept seems to be working fine), so I'm trying to better understand how this infrastructure works to help with debugging.

Related

Correct way to set up .net5 library projects with project dependencies in dev, but separate nuget packages when published

Suppose I am building two class libraries in a single solution in visual stuido. The projects are called "Core" and "Extensions".
Extensions depends upon Core.
I would like to publish these as separate nuget packages for other developers to consume, because while the Core package would always be used, the extensions package just provides some optional functionality.
When I am developing the solution in visual studio, however, it is much simpler for me to set a project dependency from Extension to Core. Otherwise (in a naive approach), building the whole solution would require the following steps:
In visual studio, commit and push Core.
Wait for the CI server to build Core and publish the nuget package to our internal feed.
In visual studio, manage nuget packages for the Extensions project.
Connect to the internal nuget feed
Get the updated Core nuget package.
This approach would work, but is obviously very tedious.
The main difficulty I have been encountering while researching how to do this is that the way all of these things interact has been changing quite rapidly over the past few years, with sdk vs non sdk style projects, nuget pack vs dotnet pack vs msbuild pack, and so on and so forth.
Perhaps the most relevant, most recent answer appears in this question How do I create an individual nuget package for each project in a solution, with project references converted to nuget dependencies? however the answer is now quite old, and is for a dot net framework style project (using packages.config), not a .net5 project.
So, can anyone provide up to date advice on how to correctly accomplish the following:
In a visual studio solution with multiple .net5 class library projects, have dependencies set up as project dependencies at dev-time, but convert each project to its own nuget package with the equivalent package dependencies at publish time.

Visual Studio dotnet core copy and paste references

I've known about copy/paste references in Visual Studio since 2010/2012. Has this been updated to work with Core 2?
Here's the SO Question asking about the old style references (before Core, and before the reboot of csproj format): Is it possible to copy / paste References from one project to another in Visual Studio?
Maybe now that dotnet add package is available, we don't need copy/paste references in VS?
"Add Google social login" walkthrough for ASP.NET Core 2.0 suggests using the dotnet CLI to add a package reference:
To install with .NET Core CLI, execute the following in your project
directory:
dotnet add package Microsoft.AspNetCore.Authentication.Google
source: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins?tabs=aspnetcore2x
Writing this answer to my own question so the "just use the CLI" folks have something to upvote.
If you are talking about NuGet package references, don't try to copy the resolved references to dll files manually (the are generated from the obj\project.assets.json file during the design-time build after loading the project).
In the new SDK-based project model and the PackageReference way of referencing NuGet packages (also available for "classic" projects), NuGet references automatically flow transitively across package references. So when your app references a library that uses a NuGet package, you no longer need to install the NuGet package in both the library and the app (and potentially test projects).
Only for "classic" references, this issue remains. However, if you need to import them into all projects (say you got a few .dll files from a 3rd party), you can create a Directory.Build.targets in the solution folder to add them to all projects in your solution (technically, this file is automatically imported into all projects in the directory hierarchy):
<Project>
<ItemGroup>
<Reference Include="AssemblyName">
<HintPath>shared-libs\AssemblyName.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
(you may want to change the reference if you want the "specific version" feature or strong-name references as described in https://stackoverflow.com/a/16580870/784387)

How to make sure nuget assemblies are added by package rather than only reference to DLL file?

I have noticed many times that developers tend to reference assemblies directly by browsing to the .dll file under the .\packages folder (installed by another project) and adding that to project references instead of installing the nuget package on that project. In that case, even though it compiles, but the Nuget Package Manager does not know that the referenced assembly is from a package, and so updating the package solution-wide does not update those references in that project. If you are doing a Service Oriented architecture where each piece of feature in your application is a separate project in the solution, then you probably have hundred of projects, and managing those references would become a nightmare. Is there any way to prevent developers from referencing assemblies directly if they belong to a nuget package? For example is there any MSBuild task to verify all references to package assemblies require the package to be installed on the project?
If your team uses resharper, they have a plugin to help with this:
http://blog.jetbrains.com/dotnet/2012/11/20/add-packages-not-references-a-nuget-plugin-for-resharper/
I'm guessing the issue is caused by people using resharper without it, since by default VS won't know to include that DLL but Resharper will find it and reference it (and not update package config without the plugin)
Also get used having people using nuget at the solution level, not project level. That will force people to update all nuget packages across the solution, and not leave you with V 1.1.1.0 on Project A and v 1.1.2.0 on Project B.

warning : All projects referencing MyProject.csproj must install nuget package Microsoft.Bcl.Build

I have an ASP.NET MVC 4 app developed in VS 2012. The app consists of a main project (MyProject), a unit-test project (MyProject.Tests), an Azure deployment project (MyProject.Azure), and a couple of general-purpose library projects.
When I right-click on either the solution or the main project and select Manage NuGet Packages, I see a bunch of Microsoft updates that have apparently become available in the last month or so. If I click on the Update All button then the updates are apparently installed without any obvious problems, but when I build the solution I get this error message TWICE:
warning : All projects referencing MyProject.csproj must install nuget package Microsoft.Bcl.Build
Ok, so I have two projects that reference MyProject: MyProject.Tests and MyProject.Azure. I can right-click MyProject.Tests, select ManageNuGet Packages, and add Microsoft.Bcl.Build. That gets rid of one of the two warnings. But VS does not give me an option to manage NuGet packages for the MyProject.Azure project.
How do I add the Microsoft.Bcl.Build package to the Azure deployment project?
EDIT:
Thanks to user swell, I now know that a Microsoft Connect issue for this problem has been opened here.
The answer provided by TheESJ is correct, however the wording wasn't clear to me. Since I cannot comment on the answer, I will provide more details here. Specifically, I was having this problem with an Azure project and the following workaround was required to make the warning go away:
When you double-click the warning in VisualStudio, you will be taken to the BclBuildValidateNugetPackageReferences target in the Microsoft.BclBuild.targets file. Above the actual target element, you should find a large comment block that talks about disabling the project reference checks. Since Azure projects cannot have any library references, it is impossible for those Azure projects to fulfill the requirements of this particular build target.
The solution? Disable reference checking from the Azure project since it is impossible to actually add a nuget package reference.
EXAMPLE
So, assume we have two projects: MyAzureProject.ccproj which references MyProject.csproj. Follow these steps:
Right-click on "MyAzureProject" in the Solution Explorer and select "Edit Project File."
Find the project reference to "MyProject." It should look something like:
<ProjectReference Include="..\MyProject\MyProject.csproj">
<Name>MyProject</Name>
<Project>{1d99490e-d140-4897-9890-238e673a5864}</Project>
...
</ProjectReference>
Add the following element inside of the ProjectReference element:
<Properties>SkipValidatePackageReferences=true</Properties>
Your project reference should now look like this:
<ProjectReference Include="..\MyProject\MyProject.csproj">
<Name>MyProject</Name>
<Project>{1d99490e-d140-4897-9890-238e673a5864}</Project>
...
<Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>
Right-click on "MyAzureProject" in Solution Explorer and choose "Reload Project."
You should now be able to rebuild and the error should be gone.
If you double click the warning it gives you instructions for disabling the warning.
It is safe to disable for projectreferences from projects that don't yet support Nuget.
See below portion in bold copied from Microsoft.Bcl.Build.targets.
BclBuildValidateNugetPackageReferences
This target can be disabled for a project reference by setting SkipValidatePackageReferences=true for the reference:
<ProjectReference Include="..\pcl\pcl.csproj">
<Project>{664a9e98-fac7-4567-a046-0dde95fddb48}</Project>
<Name>pcl</Name>
<Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>
I faced the same issue and was trying to update Microsoft.Bcl.Build.targets; which did not help.
After some investigation found that .csproj file of the Azure Service project must be modified to include <Properties>SkipValidatePackageReferences=true</Properties>.
This was not apparent from the answer of #TheESJ and so decided to post separate answer. Thanks to #TheESJ.
I encountered this issue a number of times, and the Properties method does indeed work, but when dealing with a Wix project, I had to do the following instead:
<AdditionalProperties>SkipValidatePackageReferences=true</AdditionalProperties>
When I used the Properties Xml node, I got a new error:
The OutputPath property is not set for project
'MyInstallerProject.csproj'. Please check to make sure that you
have specified a valid combination of Configuration and Platform for
this project. Configuration='Debug' Platform='x86'. This error may
also appear if some other project is trying to follow a
project-to-project reference to this project, this project has been
unloaded or is not included in the solution, and the referencing
project does not build using the same or an equivalent Configuration
or Platform.
After failing to resolve the issues with any of the above answers, I simply followed the instructions contained within the Microsoft.Bcl.Build.targets file (displayed after double clicking on the error in the build output window).
I unloaded my project (referencing Azure packages), encountering the error. Edited the project file and inserted the following...
<PropertyGroup>
<SkipValidatePackageReferences>true</SkipValidatePackageReferences>
</PropertyGroup>
...at the top of the project file before the first PropertyGroup.

Nuget: Set one project in solution as unmanaged by Nuget?

First off, let me start by saying that Nuget is awesome. I love it. That being said, there is one thing about it that I have just discovered which is really getting very annoying.
We have an in-house framework which we use for almost all of our projects. So, I recently created a Visual Studio project template for it, along with the VSIX.. had a few problems along the way due to Nuget.. it wouldn't create the new project from a template when the template was referencing the framework.. because the framework was using Nuget and it couldn't find the nuget folders in the new project created from the template. So, solution was to remove nuget from the framework project and only use Nuget for the other projects (anything but the framework). Okay, great.. that solves the problem!
However, now with every Nuget managed project that I open, it automatically adds these 2 lines back into the .csproj of the framework:
<RestorePackages>true</RestorePackages>
and
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
This is frustrating because we now need to either stop using Nuget altogether OR to keep removing these lines from our framework's .csproj file every time we want to rebuild the template.
Is there any way I can tell Nuget to ignore one project in the solution? In my case, to ignore the framework project...
With a suggestion from Nailuj and also from what I found here: http://samritchie.net/2012/09/17/nuget-packages-in-vs2012-templates/, I tried something that I thought would work, but it didn't serve my needs; that method is just for including the packages in with the new project, which for me is not helpful and doesn't solve the problem (error about missing .nuget targets folders). So, I played with it a bit and came up with something that is not ideal, but is acceptable:
Remove anything and everything to do with Nuget from the project which is to serve as a template. This then causes a problem with the referenced framework, because the framework project is expecting to be managed by Nuget and from this solution it's not, so error occurs... so:
Remove the framework project from the solution and only reference the DLL so it will build, but not complain about missing nuget folders
Rebuild
Export to template
Build VSIX using exported template
Install template
Create a new project from the newly installed template
Enable Nuget package restore on solution of new project
Open Package Manager Console
Notice message about missing packages and agree to download and install them (about 1 minute)
Remove framework DLL reference and replace with actual project (Right-click, Add Existing Project)
Rebuild and run
Celebrate!
I hope this helps anyone else who may find themselves in this predicament. If anyone has a better idea, please let me know. The bounty is still open for another 6 days, so I won't mark this as answer yet.

Resources