Reference nuget package project from another nuget package project in same solution - visual-studio

I am creating couple of .NET Standard 1.6 libraries that I want to publish as Nuget packages. They share a common libary that is a 3rd project in the same solution as the first two. The shared library has no value by itself, but I am assuming that if I want people to use both of these two libaries in the same project I should publish the shared library as a Nuget package as well. If I don't I am worried about multiple copies of the same shared library "colliding" or not properly warning when there are version mismatch issues.
Am I correct that the shared library needs to be a Nuget package as well? Is there a way to reference the shared library as Nuget package, but use is as if it was a project reference when developing / debugging the 2 main libraries in this solution? If I had to publish to Nuget.org and wait for the package be propagate through the Nuget.org system before using a changed version in a debug session that is REALLY going to slow down development. Note that these are .NET Standard projects. I found How to reference related projects in the same solution when Nuget packages are the required output but that doesn't seem to work with .NET Standard (getting errors during pack) and I am also not sure if .NET Standard not using nuspec files anymore also would cause a problem.

I am also not sure if .NET Standard not using nuspec files anymore also would cause a problem.
The .NET Standard still using .nuspec files, and using old school nuget pack and a .nuspec will resolve this issue.
As per document dotnet pack:
NuGet dependencies of the packed project are added to the .nuspec
file, so they're properly resolved when the package is installed.
Project-to-project references aren't packaged inside the project.
Currently, you must have a package per project if you have
project-to-project dependencies.
So, to include project-to-project references in NuGet packages, you need manually maintain a .nuspec file and add dependencies. You can refer to the Create .NET Standard packages with Visual Studio 2015 for detail info.
Besides, dasMulli has provided a simpler way to do this by involving adding and hooking up a custom target :
<Project>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeP2PAssets</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\testprivatelib\testprivatelib.csproj" PrivateAssets="All" />
</ItemGroup>
<Target Name="IncludeP2PAssets">
<ItemGroup>
<BuildOutputInPackage Include="$(OutputPath)\testprivatelib.dll" />
</ItemGroup>
</Target>
</Project>
The source code comes from: "donet pack" is not including project references

Related

Package .NET framework DLL and use it in .NET standard project

I have a vendor provided DLL which is based on .NET Framework. I do not have access to code and I only have the DLL. I have packaged this DLL into a nuget package and now I am trying to refer this into a .NET standard project. But I am getting warning as - Package 'MyPackage 0.0.1' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETStandard,Version=v2.0'. This package may not be fully compatible with your project..
If I refer the DLL directly into a .NET standard project it doesn't show this warning. But using it after creating a nuget package shows that.
I also tried creating a .NET standard lib project, added DLL reference and then created a nuget package but still it was showing same warning.
Is there another way of doing it? Vendor doesn't provide DLLs targeting other frameworks and I have to use it after packaging it into Nuget because of requirements.
In my side, I test the situation as you described. Create a net standard lib project called test, then use this node to include into the package.
1) create a net standard lib nuget project called test and only add this node under test.csproj file:
<ItemGroup>
<None Include="xxx\xxx\xxx.dll"(the whole path of the net framework dll) Pack="true" PackagePath="lib\$(TargetFramework)"></None>
</ItemGroup>
2) right-click on the net standard test project-->click Pack button and you can get the new version of the nuget package.
Before you install the nuget package into another main project, you should first clean nuget caches or delete all files under C:\Users\xxx(current user)\.nuget\packages.
And I did not face the issue in my side with all the above steps.

Nuget packages with both debug and release

In our work we have one team that develops libraries and other teams that develop projects using those libraries.
The libraries team has much more experience than the projects one.
We created this environment here:
All the libraries are in nuget packages, in a nuget server, in azure devops.
We have source link in Azure devops.
But when we deploy the libraries, we have to choose between debug or release, and we have the pros and cons of each.
My ideal nuget package would have both debug and release, and would select the same as the project running it.
this way I would have better debugging for the projects team, and maximum performance on the releases.
I talked with https://twitter.com/rrelyea and he gave some ideas, but they seem to complicated for the other teams to implement, or complex do manage.
Like 2 nuget servers, one for debug, and one for release, and configure those different ones on the machines and on the build server.
Or 2 nuget packages, with .debug and .release on the name of the package, and configure the project to load a diffent one on each mode.
The real problem is that I need a guarantee that all the packages have the same id and version on both servers.
Isn't there a more automatic way to pack the packages?
Simple if it's debug use the debug, if it's the release use the release.
By the way, how much performance difference is between debug and release in this case?
Isn't there a more automatic way to pack the packages?
Actually, nuget package does not have a mechanism to let a project to reference the debug output files or release output files based on the configuration of the main project.
And when you pack a project, it does not have a function to include the Debug or Release output files at the same time and then let the main project-------when using Debug, reference the Debug content of the nuget, when using Release, reference the Release content of the nuget.
So far, nuget is not yet so flexible, and it can't do the functions you mentioned above.
=====================
As a suggestion, you should create two nuget packages(Debug or Release) of the project and then manually install the corresponding package as required.
You can create a net standard library project, and add these in xxx.csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>PackageName</RootNamespace>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<PackageId>PackageName_Debug</PackageId> //name the nuget package which contains Debug key name
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<PackageId>PackageName_Release</PackageId> //name the nuget package which contains Debug key name
</PropertyGroup>
<PropertyGroup>
<Version>1.0.0</Version>
<Authors>your_name</Authors>
<Company>your_company</Company>
</PropertyGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<None Include="$(ProjectDir)$(OutputPath)$(AssemblyName).pdb" Pack="true" PackagePath="lib\$(TargetFramework)"></None>
<Compile Update="Class1.cs" Pack="true" PackagePath="Resource">
</Compile>
...// add any source files
</ItemGroup>
</Project>
And you can switch the Configuration to Debug or Release to build your project to generate the nupkg file under output folder.
Note:
1) To generate a debug nuget package, you should contains the pdb file and source files into the nuget package and then you can debug it in the main project. There is a similar issue which contains the detailed steps about it.
2) You can define the package_id directly in the new sdk format project. And you should add Debug or Release to distinguish between them.
More info about packing new sdk format project, you can refer to this document.
==============================
In addition, if you still want the initial feature(contain Debug or Release in the same package), you could suggest a feature on our User Voice Forum and I hope the Team will consider you idea carefully and give a satisfactory reply.
Maybe... just add .pdb files from debug folder to Lib using Nuget Explorer

How do you get NuGet package restore to work on locally deployed packages stored in VSIX targeting Visual Studio 2019?

I am aware there are multiple questions on this topic already, but they all seem outdated. To clarify, I am using the "new" VSIX manifest format, and trying to follow the official instructions here: https://learn.microsoft.com/en-us/nuget/visual-studio-extensibility/visual-studio-templates
I have one project template and a couple of item templates that go with it. They all depend on deploying a NuGet package that should come bundled locally with the VSIX. I have examined the resulting VSIX file and all the files seem to be in the right place:
The project template has the required XML for declaring which packages to install:
<WizardExtension>
<Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
<WizardData>
<packages repository="extension" repositoryId="VsixID.etc.etc">
<package id="Rx-Linq" version="2.2.5" />
</packages>
</WizardData>
The repositoryID matches the ID attribute in the .vsixmanifest file.
There is an individual Asset entry for each package, with the form:
<Asset Type="Rx-Linq.2.2.5.nupkg" d:Source="File" Path="Packages\Rx-Linq.2.2.5.nupkg" d:VsixSubPath="Packages" />
I have removed all packages.config and all the package references from the .csproj file installed by the VSIX (and even from the VSIX project itself just for good measure).
I have inspected the output VSIX and there is indeed a Packages folder in the VSIX containing all the .nupkg files. This folder is indeed unpacked and copied into the Visual Studio Extensions folder.
Despite all this, when I create a new project with the template, VS displays an error message saying: Failed to restore package from C:\users\<pathtoextensions>\Packages.
The thing is, the .nupkg files are actually present in the exact folder that the error message refers to.
I have been searching this for days and I can't seem to find any reference to best practices that actually work. It seems like these VSIX manifests are geared towards the legacy packages.config way of doing things, and there are discussions about how to extend them to use PackageReference instead.
Can anyone give any advice at all at how we are supposed to proceed going forward? Are packages not supposed to be deployed with the VSIX anymore? Are we supposed to just fill in the project with PackageReference entries and just let the user resolve them manually?
I feel like I am missing something fundamental here and any insight would be extremely valuable.
Update: I have also opened an issue on the NuGet github repository, as this is clearly a problem with the PackageRestore feature when restoring packages stored in a VSIX installer. Everything else mentioned in this question is working as intended and expected, except the package restore.
How do you actually include NuGet packages in Visual Studio Project
Templates VSIX targeting Visual Studio 2019?
Actually, there is no way to specify in a VS project template project that nuget packages can be used both using packages.config and PackageReference. Only two project templates of nuget management types can be created separately.
I have an easy way and since you have some issues with PackageReference format, you can try this funtion:
PackageReference
1) add these reference node in projecttemplate.csporj file:
<ItemGroup>
<PackageReference Include="Rx-Linq">
<Version>2.2.5</Version>
</PackageReference>
</ItemGroup>
2) When you create a project by this project template, please check these two options and VS will automatically read xxx.csproj and then recover the corresponding nuget package based on the information in it during build process.
Note: also make sure that the nuget url is checked and can be access under Package Source.
packages.config
In additon, for packages.config, you can just create a file named packages.config and then add your nuget info into it:
1)
2) add these into projecttemplate.csproj file:
<ItemGroup>
<Content Include="packages.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Reference Include="Rx-Linq, Version=2.2.5, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
<HintPath>..\packages\Rx-Linq.2.2.5\lib\net472\xxxxxxx.dll</HintPath>
</Reference>
</ItemGroup>
Note: if this nuget package has dependencies, you should also add them(above steps) into packages.config and xxxx.csproj file. This funcution is a little more complicated than yours but it works. So, I recommend that you use PackageReference format.
More info you can refer to this similar issue.

Project reference VS NuGet

How should I reference to another project A from project B in the same solution?
What do I gain and what do I lose if I:
Add the reference to project A as a project reference.
Install the NuGet package of project A in project B.
Things that would bother me are build dependencies, versioning..?
Or does this totally destroy the purpose of a solution?
Project reference VS NuGet
Project reference or NuGet is a very common problem in our development process, we need to choose which one to use based on our actual situation.
For example, if the referenced project A is modified frequently during the development process, we recommend to use Project reference. Because if you use nuget, you have to rebuild the referenced project, recreate the nuget package, reinstall that nuget package to the project B, even you have to publish it to the server. This will bring a lot of unnecessary work and we often forget to update our nuget package after we modify the referenced project A. If you use the project reference, you will not have these problems. The modified referenced project A will be update automatically before we build the project B.
On the other hand, when we share our referenced project A out of solution, or share that project to others, nuget will be a better choice. It has more portability.
So the project reference will be recommended when you reference to another project A from project B in the same solution, the nuget is more appropriate when share the reference project out of solution or share project to others.
Besides, there is a Visual Studio extension NuGet Reference Switcher, which which automatically switches NuGet assembly references to project references and vice-versa.
Hope this helps.
With the first approach, you gain in simplicity, since you don't need to generate a new version of the ProjectA nuget package, every change you make in it (i.e. ProjectA.nupkg).
However, with the second approach, you gain in portability, since you can easily share the same nuget package with other projects / solutions.
Personally, I create nuget packages only for projects whose goal is to share with other solutions. (E.g. libs and frameworks).
Hope this helps you decide!
Nowadays with the new csproj format the you can use both at the same time (if you have both projects in the same solution).
In your example, you could reference project A from project B as a project reference. Then, if you want to release project A as a NuGet package you just need to add the following tag to it's csproj inside a PropertyGroup:
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
The plot twist: If you want to release project B as a NuGet Package too just add the GeneratePackageOnBuild target - MSBuild will set projectA.nupkg as a dependency in projectB.nupkg.
This way you can work internally with your projects while at the same time release them as packages to third parties or other teams.
You could use both: project references during development (faster), and package references during production.
In your .csproj project file:
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<ProjectReference Include="../../../Library1/Library1.csproj" />
<ProjectReference Include="../../../Library2/Library2.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'!='Debug'">
<PackageReference Include="Library1" Version="1.0.0" />
<PackageReference Include="Library2" Version="1.0.0" />
</ItemGroup>
In development: project compiled in debug mode, so the project reference will be used.
In production (CI server, docker container): project compiled in release mode, so the package reference will be used.

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)

Resources