Unnecessary folders from NuGet packages - c#

My c# app target framework is 4.6.2
I downloaded from NuGet some packages, my question:
when I open my app in file explorer, under packages\somepackage\lib I have this:
do I really need net 40 and net45 folders?
can I delete that? how do I know what is unnecessary?

Reason why NuGet keep the folders
Nuget uses two different methods to manage packages of every project:
packages.config
PackageReference
packages.config is only used for old project files which cannot import and reference NuGet packages automatically. NuGet will change the *.csproj file to add the references. Because it changes the code which is under version control and cannot use an absolute path, so it should put the NuGet package cache folders in every solution. In this case, NuGet might have the ability to remove the useless folders. But this is the behavior of legacy NuGet version (version 2.x). NuGet doesn't want to fix a legacy behavior.
PackageReference is the new behavior of NuGet references. NuGet put all the NuGet cache in a common folder so that it will not take too much disk space by the same NuGet packages. In this case, NuGet doesn't know every lib version on your whole computer projects, so it can't remove the useless version folders.
Conclusion: NuGet doesn't know whether it is safe to remove them in PacakgeReference and doesn't want to remove them in packages.config.
Upgrade packages.config to PackageReference
UPDATE:
From VisualStudio 2017 version 15.7 there is an integrated feature that allows you to do this upgrade without using third party tools Migrate from packages.config to PackageReference
In Solution Explorer, right-click on the References node or the packages.config file and select Migrate packages.config to PackageReference...
You can try a Visual Studio extension NuGet PackageReference Upgrader to upgrade your packages.config to PackageReference so that it will not store libs in every solution folders to eat up your disk space.
P.s.
NuGet take me nearly 10GB on my C:\ .

Related

Visual Studio SourceLink Nuget Integration with Separate Solution Debugging

I have a library of nuget packages we use throughout our solutions, hosted in Azure Artifacts. These nuget packages are built with debug enabled so symbols are created and included in nuget packages.
Our projects in Visual Studio (mainly Net Core 3.1) reference these nuget packages in the normal way using Nuget Package Manager.
Each solution has SourceLink enabled so if I have any debugging requirements which require stepping into code within the referenced nuget package, I can set a breakpoint and do so quite nicely as Visual Studio downloads the sourcecode directly from Azure Artifacts.
That all works perfectly.
The issue is a productivity one. If code within the nuget package needs to be changed, I have to open the solution for the nuget package, change it, push it and wait for Azure to build. When built, I go to Nuget Package Manager, update the package, restart the app and 'hopefully' have resolved the issue. For something tricky, I can loop this process a few times which is a productivity killer.
Is there any way to debug directly in the solution for the nuget package from the solution referencing it? Or does anybody have a better process they use which is more productive?
You may try to use floating version that can resolve to the latest version in nuget. In this way, when there is updated package, your solution will load the latest version of the package during build.
<ItemGroup>
<PackageReference Include="NuGet.Packaging" Version="*" />
</ItemGroup>
Is there any way to debug directly in the solution for the nuget package from the solution referencing it?
Using project reference instead of the nuget package when you need to frequently modify and debug the source code in the nuget package.
When you consider production efficiency, please consider using project reference, when you consider portability, please try to use nuget. You could check my previous thread for detailed explanation.
For your situation, you could add the project for the nuget package to your referencing solution by the option Existing project:
Then select the project file .csproj for the nuget package.
After adding that project into your solution, you could add that project as project reference for your referencing project. Now, you could directly modify and debug the project for the nuget package.
When you finish this stage of work, you can return to the solution where the project for the nuget package is located, pack the new version of the nuget package and publish it.

Shipping msbuild task as nuget

I need your help.
I'm developing an msbuild task that performs certain actions upon msbuild.
I want my users to be able to download and install a nuget package and once the package is installed the build task will be part of the build process.
I know how to release a nuget package and i know how to includes a custom targets file together with the nuget, what i don't know is how to add the import statement to the csproj upon nuget installation:
Is there a way to do so or am i asking for too much?
Thanx!
Gilad
The docs aren't in the easiest to find place, but here's a link to the docs on including MSBuild props/targets files in your package.
Basically, you put the file in the package in the location build\<tfm>\<package_id>.props. For example build\netstandard2.0\MyPackage.props. If you want your build targets to be included in all TFMs, you can use build\<package_id>.props, but if your package also contains other assets like lib/ or contentFiles/, the "no-TFM" build files will cause "asset-target fallback" to fail, so if your package has only net472 libs, and the build files, a project targeting netcoreapp3.0 will get only the build assets, none of the net472 assets. If your build files are in a TFM folder, then NuGet's asset target fallback will select both the lib and build assets. So, I strongly encourage everyone to always use the TFM folder.
The docs need to be improved, but the table explaining lists build, buildTransitive, and buildMultiTargeting. Projects using packages.config only use build assets under build. Projects using PackageReference only use build and buildMultiTargeting assets when the project references the package directly. Assets under buildTransitive get selected when the package is pulled in transitively, rather than directly. The difference between build and buildMultiTargeting is complex. If you understand the concept of "inner-build" and "outer-build" in multi-targeting SDK style projects, that's the difference (build is inner-build), otherwise only use build.
I should update the docs to have this information.

Does nuget create separate packages?

I am still confused about how nuget works. I git clone a C# .sln project and from console, and I ran this nuget command:
nuget restore my_project.sln
it came to my attention that it generates two packages containing all dependencies required by my_project.
One package is located under my_project/src/packages, the other c:/users/my_user_name/.nuget/packages. While the file structures are a little different the DLL files in both packages are identical.
That confused me. Why two packages are generated by default? Where exactly does Visual studio look up for the project's dependencies?
More important, which config file should I update in order to only keep a copy of the dependencies and how can I specify the location in my file system for the packages?
Recent versions of NuGet support package references in project files.
This format will restore packages on demand, using your %USERPROFILE%.nuget folder as a cache. And your solution folder won't be "polluted" by a packages folder with binaries that you probably don't want to commit to source control.
VS2017 allows you to select "PackageReferences" or the older "Packages.Config" format when you create new projects (Tools/Options/NuGetPackageManager/General).
You probably have some projects in your solution that use the older "Packages.config" format, which stores in the packages folder in the solution directory, and newer "PackageReferences" format.
To convert the older projects to the new format, I believe you need to remove all packages from the project, then add them back again. They will be added using the default format you selected, with a prompt for confirmation if you selected "Allow format selection on first package install".

How to handle packages such as EF, MVC4, WebPages and friends in my project repository

I have an asp.net application using EF, MVC4 and some additional packages. Whenever I try to open the project on a different PC I have issues with the installed packages. My references are marked as missing, and the code is far from compilable. Last time I solved it by deleting references and packages and installing the needed packages one by one. I find the solution tedious. Is there any better, global solution for this? How is this supposed to be done? Shouldn't this be automated?
Thanks for the help and pointers!
UPDATE
I DO use NuGet Packages, (otherwise it would be very hard to get all these dlls) but somehow I always end up with uninstalling and reinstalling the packages to make my project work. I always end up with wrong versions and not compiling code.
I end up doing the following:
Delete package.config
Delete dependencies from the web.config file
NuGet Package Manager Console:
PM> Uninstall-Package A.B.C
PM> Install-Package A.B.C
Clean - rebuild project and hope for the best
I think Uninstall - Install can be replaced with Update-Package –reinstall A.B.C
I was hoping that there is a simpler solution for this.
If using visual studio; you can enable automatic package restore; this article outlines nuget in detail.
If you go to Tools -> Options -> NuGetPackage Manager you can make sure that the auto download is enabled. See the screenshot below.
Without knowing which references are broken, I would assume that you can at least use NuGet Packages to manage Entity Framework and additional framework references.
As lucian.jp said nuget it probably the way to go. At my company, we usually will go out of our way to find and use only packages that have maintained nuget packages, and even most of the core Microsoft ones have them, for example https://www.nuget.org/packages/Microsoft.AspNet.Mvc/
For the other ones, keeping a little thirdparty folder with external assemblies/dlls in the root of your repository and then reference from your project to that instead of from some random place on your hard-drive. I.e. check the third party assemblies into your project somewhere that is not your bin directories.
So if you have an existing project, here is what I suggest you do to avoid future issues:
For each of the assemblies, including your MVC ones, find the nuget equivalent, remove the dll from your project and add it back using the nuget package manager.
Get a copy of all the remaining assemblies and create a folder in the root of your repository and place them in there, then delete all of them and add them back in referencing the dlls from that folder.
If you are using git I'd also use .gitignore to not check in your bin directories. Which will force a new deployment of your code to get the assemblies from their respective sources.
Use Nuget for DLL packages like EF and MVC. But do not use Nuget for JS / CSS packages instead go for bower. Nuget packages for CSS and JS libraries are good but just their installation and uninstallation is tricky and may not match your project structure.

Directory structure for a NuGet published github hosted project

For a github hosted open sourced C# project which is also available via NuGet, how should one organize the source? Specifically:
should the .nuspec file be in the github repository?
should the .nuspec file be in the same folder as the .csproj file?
how about the NuGet package tree (the /lib, /content stuff), since is generated, should it be in git?
My thinking is that the NuGet part is separate from the github hosting, as in the project source are available but the .nuspec is not, since the publishing in NuGet is not an open source operation per-se. None wants that every fork to build and publish a new NuGet package, so that the open source Foo package ends up in the gallery as 'Rick's Foo' vs. 'John's Foo' vs. 'Alice's Foo' etc.
But on the other hand I do want the github source depot to act as a one-stop repository for the project, if I open my other laptop and enlist from there, I should be able to build/package/push w/o recreating the whole NuGet infrastructure from scratch (ie. only enter my API key, nothing more).
These two requirements are contradicting each other, Did I miss something obvious?
I would do the following:
Commit the .nuspec file next to the .csproj file
Add a nuget.config file which moves the packages folder a level up.
Enable package restore in the solution and do NOT commit the content of the NuGet package repository
Create an msbuild file (or whatever build vehicle you like) which has:
a "build" target which builds the source and creates the nuget package
a "publish" target which pushes the NuGet package to nuget.org and takes your API key as a parameter.
I personally maintain the version number of the nuget package in the .nuspec file and manually update it when I do a "release". This way I can tag the exact release I pushed to the NuGet feed.
With this setup a build in Visual Studio does not produce a NuGet package but all tools are available in the repository to do so.
The Folder Structure looks like this:
.\Docs\ ==> not in source repo
.\Packages\ ==> not under source control
.\Src\ ==> git repo here
.\Src\MySolution.sln
.\Src\.gitignore
.\Src\MuRules.ruleset
.\Src\build.proj ==> msbuild file to build everything.
.\Src\MyProject\MyProject.csproj
.\Src\MyProject\MyProject.nuspec
.\Src\MyProject\nuget.config
.\Build\ ==> not under source control
.\Build\Debug\
.\Build\Release\
.\Build\Publish\
Be aware of this bug in the Package Restore feature, it will ignore the packages location you configured. http://nuget.codeplex.com/workitem/1990 ==> This is fixed in Nuget 2.7
On nuget v2.8, I just need to modify .gitignore and add:
packages/
This will exclude the nuget packages folder from committing. When you build the new checked-out source code, the packages would be downloaded and restored. Make sure package restore setting has been enabled but I think it's been enabled by default on v2.8.

Categories

Resources