NuGet, Packages.config, .csproj and references - c#

I have a question so that I can better understand NuGet packages, packages.config and the .csproj file.
It is my understanding that the setting in the NuGet Package Manager >> General for default package management format determines if your project uses packages.config or the .csproj file for resolving and restoring packages.
In my project we have selected Packages.config.
No problem it compiles and runs. So I decided to test if it would run without the reference for a dll in the .csproj file, as it is my understanding it does not use or need this. This is an incorrect assumption as though the package is in the packages.config file, when I removed the reference in the .csproj file there was an error in my project and the project would not compile.
I also noticed that if the dll is not in the references in the Solution Explorer that it fails to compile as well I( I assume these are the .csproj references).
So I am not clear on the role of the .csproj file for a Packages.config Management format for NuGet packages and the references in Solution Explorer.

The difference is on how you manage your NuGet references.
Before VS2017 the information what NuGet packages to be used during assembly was stored in files packages.config.
Since VS2017 there is a new option called package references which stores this information in the project (.csproj) file.
https://devblogs.microsoft.com/nuget/migrate-packages-config-to-package-reference/

Before VS2017 and .NET Core, NuGet was not deeply integrated into MSBuild so it needed a separate mechanism to list dependencies in a project: packages.config or project.json. Using Visual Studio solution explorer's References context menu, developer adds .csproj references to restored packages in a solution-wide folder managed by NuGet.
The reference added to the project file .csproj by Visual Studio looks like this:
<Reference Include="EntityFramework, Version=6.0.0.0"><HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath></Reference>
Starting with VS2017 and .NET Core, NuGet becomes a first class citizen in MSBuild. NuGet package dependencies are now listed as PackageReference in the SDK-style project file .csproj
A reference now looks like this:
<PackageReference Include="EntityFramework" Version="6.4.4" />

Related

How can we use managed nuget packages in c++/cli project

I want to consume managed nuget package in c++/cli project. Is there a way to do that?
For example my scenario is almost like this:
I have created a C# project(MainProject) and added EntityFramework nuget package to that project.
I have created one more C# project(TestCSProject) and added MainProject as reference to that project. Then automatically in references entityframework is also added
I have created one C++/CLI project(TestCLIProject) and added MainProject as reference to that project so that I want to see whether I can use entityframework.
But that didnt happened.
So I want to know how can I use managed nuget package in c++/cli project
C++/CLI project can use nuget packages using packages.config (in VS2019 still there is no PackageReference support for C++, PackageReference for NuGet packages in C++ projects). As pointed in the comments, C++/CLI should be used for interop with native code only. Anyway there may be a need sometime to use nuget packages here.
In Visual Studio 2019 the following worked for me for a C++ project referencing .Net Framework:
Go to package manager console: Tools -> NuGet Package Manager -> Package Manager Console. Then install nuget package(s) (instruction from Microsoft). E.g. EF nuget installation could be like:
Install-Package EntityFramework -Version 6.4.4 -ProjectName TestCLIProject
After nuget installation a packages.config file will be created in the project's folder and added to the project. E.g. after EF nuget installation packages.config could be like:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.4.4" targetFramework="native" />
</packages>
Add reference(s) to dll(s) from the nuget. Project -> Add Reference... -> Browse... -> locate solution's folder -> go to packages folder -> go to nuget's folder -> locate dll(s)
For example for EF this resulted as .vcxproj was updated with:
<Reference Include="EntityFramework">
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServer">
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
Project is ready for build. If Visual Studio has opted out Tools -> Options -> NuGet Package Manager -> Automatically check for missing packages during build in Visual Studio, then nugets could be manually restored e.g. in Package Manager Console with Update-Package command.
With the newest Version of VS2022 (Visual Studio 2022 version 17.3) you can now as well use PackageReference in your C++/CLI project. Just make sure you have added
<EnableManagedPackageReferenceSupport>true</EnableManagedPackageReferenceSupport>
to the PropertyGroup with Label="Globals" in your .vcxproj file. Furthermore please be aware that your C++/CLI project must be targeting .NET Core or .NET 5+. As you can read in the Release notes this doesn't work (and neither is it planned to be supported in the future) for C++/CLI projects targeting .NET Framework.
With this enabled you can now also use the NuGet Package Manager by
In Solution Explorer, right-click "References" and
choose "Manage NuGet Packages"
just like it is described in the Microsoft documentation.

Visual Studio References shows NuGet package that is not referenced

I converted a .NET Framework 4.7.2 project from packages.config to PackageReferences format by right clicking the packages.config file within VS 2019.
Since then Visual Studio shows blue icons of a NuGet package which I uninstalled from the project in the References node. What is truly weird is that without this package the build should fail as it is used within the code, but the build succeeds!
There are no packagereference to this NuGet package in the .csproj
file.
There is no packages.config file in the project directory
I deleted the .vs folder and the older packages folder
Restarted Visual Studio
Problem Remains
uninstall-package command fired within Visual Studio says the
package is not installed.
Yet the Reference (Blue Icon) is shown and the project builds!
Question
How do I completely remove this package from the project?
How do I stop Visual Studio from referencing this package for now?
===============================
If your project does not reference any other projects or just reference a project which does not install the same nuget package, I think the issue is related to your project itself or VS environment.
And in this situation, it is quite strange that the blue icon of the nuget package still stays on the solution explorer while you have already uninstalled the nuget package.
Please try the following suggestions:
1) disable any third party extensions under Extensions-->Manage Extensions-->Installed
2) clean nuget caches and reset vs settings under Tools-->Import and Export settings-->Reset all settings
3) then close VS, delete cache files under
C:\Users\xxx(current user)\AppData\Local\Microsoft\VisualStudio\16.0_xxx\ComponentModelCache
and also delete .vs hidden folder, bin and obj folder.
4) then restart VS to test whether the issue persists.
Besides, you could use devenv /safemode to start a clean and initial VS and then test your project.
=================================
If your situation is this one:
Your project B has referenced a project called Project A while A has also installed the same nuget package. And project A uses PackageReference nuget management format.
Although you have uninstall the nuget package on Project B, your obj folder still has files like project.assert.json,xxx.nuget.g.props which is a feature of PackageReference. Due to it, the nuget package management format of Project B is the same as the Project A and will transmit the dll from the Project A into Project B so that you can use the dll in the project B.
And that delete .vs hidden folder will remove the nuget package format PackageReference of Project B since you already uninstall all the nuget packages on Project B but the PackageReference content of obj folder still exist.
So you should close VS, delete .vs hidden folder, bin and obj folder of the Project B at the same time.
Note: Rebuild and Clean will not delete the previous restore files.
If this does not work, I think you have written this xml node under B.csproj file:
<PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
So you should check in your project B carefully and it will still restore the files project.assert.json,xxx.nuget.g.props,.... as PackageReference.
Therefore, if you have, delete this node, also delete .vs hidden folder, bin and obj folder.

Reference project in two ways

I have a project that is called framework and I have modules projects which depends on this framework project.
The problem is: Some developers on my team will have this framework code and others won't. I want to know if there is a way that if Visual Studio doesn't find this reference, it will automatically get this frameworks libs from nuget package.
You could use Conditions to include the project only if it does exist:
<ProjectReference Include="..\..\Framework\Framework.csproj" Condition="Exists('..\..\Framework\Framework.csproj')" />
<PackageReference Include="MyCompany.Framework" Version="1.0.0" Condition="!Exists('..\..\Framework\Framework.csproj')" />
You have two options to reference other projects:
Project References
This is typically done using a monorepo approach and most times all projects are part of the same solution.
If you want to reference projects from other repositories, Git sub modules may be an option https://git-scm.com/book/en/v2/Git-Tools-Submodules
Project references look like this in your my-project.csproj file:
<ProjectReference Include="..\..\Modules\Core\Core.csproj" />
NuGet Packages
Here you build your framework and publish it as NuGet package. Then you reference the package (not the project) when needed and Visual Studio will download the specified version from your NuGet repository.
Two options to setup your own NuGet repository:
https://learn.microsoft.com/en-us/azure/devops/artifacts/get-started-nuget?view=azure-devops
https://www.sonatype.com/nexus-repository-oss
You can also use NuGet packages from local file system How do I install a NuGet package .nupkg file locally? (personally I'd not recommend this for most scenarios)
Reference NuGet packages in your my-project.csproj file:
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
Or using visual studios package manager: https://learn.microsoft.com/en-us/nuget/quickstart/install-and-use-a-package-in-visual-studio
Note that you have to add your NuGet repository feed first: https://learn.microsoft.com/en-us/azure/devops/artifacts/nuget/consume?view=azure-devops
See also
Is it possible to reference a project that exists in the solution and use NuGet package reference as fall-back if not in .NET Core?

Nuget Package without Package.Config?

I encountered a solution (.Net Full framework) Where there are no package.config in the solution and Feeds coming from In house Nuget servers.
Where list of packages are maintained, if not in Package.Config?
Where is the list of packages are maintained, if not in Package.Config?
First, you should make sure you have that solution have already installed the nuget package, once you install a package, NuGet will add Package.Config file to your project to record the dependency in either your project file or a packages.config file.
If you confirm that your solution has a nuget package installed, but there is no Package.Config file, your nuget package should use another management method: PackageReference
Edit your project, you will find following PackageReference list:
<ItemGroup>
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
</ItemGroup>
See NuGet is now fully integrated into MSBuild for more details:
In the past, NuGet packages were managed in two different ways -
packages.config and project.json - each with their own sets of
advantages and limitations. With Visual Studio 2017 and .NET Core, we
have improved the NuGet package management experience by introducing
the PackageReference feature in MSBuild. PackageReference brings new
and improved capabilities such as deep MSBuild integration, improved
performance for everyday tasks such as install and restore,
multi-targeting and more.
The packages.config file could be somewhere else? In that case look in your msbuild project file (i.e. *.csproj, *.vbproj, *.vcxproj) and see where the references to that nuget assembly are coming from. Then look in that directory for the packages.config file. It might be more complicated than that, in which case, it's useful to do a global search for packages.config in your repo, to see where they reside (If they do exist at all).
This is a common practice: To have one project specify the nuget package, and all the other projects borrow it. As Jon said, this is really dependent on how the folks at your company and department set up your builds and dependencies.

Reference DLL from NuGet folder inside ASP.NET Core project on full .NET framework

I have created a new ASP.NET Core project which targets the full .NET 4.6 framework. So essentially what I want is to create an ASP.NET Core web application with the new .csproj format and the new dotnet tooling, but still target the full framework because we have many dependencies which cannot be ported that quickly to .NET Core.
There are some NuGet packages that include many DLLs, but after adding a PackageReference it only copies one DLL into the bin folder of the web application. Other DLLs I need to manually reference.
For example:
<ItemGroup>
<Reference Include="CustomDll">
<HintPath>..\packages\CustomPackage\version\lib\CustomDll.dll</HintPath>
</Reference>
</ItemGroup>
Now the problem is that with the new tooling and NuGet versions there is no packages folder under the solution path. It is typically in my users folder under .nuget\packages\....
Is there a macro that I can use with the new MSBuild to reference the global nuget folder or a setting that I can change so that the build actually copies all NuGet packages under the solution directory?
It looks like the dll in the NuGet package is placed directly in the lib folder and not lib\net45 which would enable the automatic tooling in that case. (The NuGet package has probably been manually assembled).
As a workaround, you can set the HintPath to $(NuGetPackageRoot)the.package.name\1.0.0\lib\the.dll.

Categories