How to manage Nuget Packages used more than once - c#

I am a dinosaur developer, so NuGet is relatively new to me, I am used to manage third parties open source libraries having a single project with the code or the binaries, that I will keep updated when necessary and this project publishes the dll(s) on a common folder from where I reference the libraries in all my projects. This makes easy to maintain the third party libraries and in my projects I just need to rebuild when I update the library and all goes OK. Now many open source projects publish their libraries on NuGet and it is easy to reference them in the projects, but I dread the fact that I have to download a copy of the library for each project in which I use it, this, in my opinion is something that can lead to chaos. Especially if I have 2 projects that build dlls that end up using 2 different versions of the same packages and are used both in an application with problems and conflicts. So my question to those who use NuGet from a longer time is:
Can I proceed with NuGet packages as with other libraries and create a project that references them, use it to publish the dlls in a single folder and then reference the dlls of the packages from my dlls and applications on the published folder.
I hope I've been clear. Thanks for any thoughts you can share on this topic
Sabrina

Having all your 3rd party libraries for all your projects in a single folder can lead to dll versions hell. If you update a single dll which contains breaking changes and which is referenced by other projects, then you will have fix/rebuild all projects that references it.
To resolve the issue with downloading the same packages for every project you can create a local repository and configure Visual Studio to use your local repository. So if your local repository contains a single version of log4net, you'll be able to use only that specific version. Even more you can configure repository to use a shared folder, in this case all developers and even your build server will be able to use that repository.
There are a lot advantages of using NuGet, such as saving a lot of space on your hard disks and others. For example I created NuGet packages for our internal framework, so all our projects just reference those packages, rather than each project has its own version in its bin folder.

Related

How to create and manage subsites from main site in ASP.NET Core 6 MVC?

We have created multiple application solutions in ASP.NET Core 6 MVC.
I want to use each solution under a single solution so that I can use common menus/submenus in all applications.
Also not sure how will handle session in this case.
Example: we have created 4 separate solution modules for Admin, Employees, Department, Students.
Now I am creating a new Login solution which will have login functionality and menus.
I tried by creating DLL for each solution and referencing in Login solution but it's not working properly also static files are not getting added.
All modules for a single application should rather go in a single solution with multiple projects, if feasible. Each project yields a binary assembly that can be directly referenced in other projects. This prevents code duplication by allowing multiple projects to reference the same code. Using multiple solutions can lead to problems regarding referencing paths. There is also a big drawback of spliting your application into multiple solutions: your application's code cannot be accessed in full in the development environement, making refactoring harder.
Since Visual Studio 2022 is now 64bit, you can have solutions with a large amount of projects with little performance drops.
If you really need to have dependencies across multiple solutions, you should turn towards nuget. Nuget is the package manager for dotnet. After compiling a project, you provide some metadata to create a package. Then you publish the package to the repository. Other solutions can reference the package and the linker will download the binaries from the repository. Nuget packages support semantic versioning and you can reference specific versions of a library.
However, this will require you to write your code like a quality library. It means early design thinking, strong QA, and heavy testing are required so you don't ping-pong updates between your libs and their clients. This is why this strategy is more designed towards sharing libs accross multiple applications.
There are also on premises solutions if you don't want to upload your binaries to the internet. You can create a nuget repository as simply as creating a new directory and adding the path to the list of nuget packages references sources in Visual Studio. Nuget packages can be shared across your intranet using a simple SMB fileshare. If you need better access control, you can install a local copy of NugetGallery.
Details on nuget usage are availble in Microsoft documentation about nuget.

How to handle NuGet dependency version resolution for the whole solution

I'm looking for a simple way to manage NuGet packages for the whole solution, to prevent conflicts between transitive NuGet packages when assembling all files into one installer.
When building a project all direct and indirect dependencies are analyzed and the NuGet resolution picks up the best matching version for each NuGet that is at least the same version as the lowest version and might also create binding redirects if necessary. (all good and fine)
The problem we have lately encountered was when we build the whole solution (200+ projects) at once, the resulting NuGet versions between all top level projects might not be identical. And due to the fact, that all resulting DLL and EXE files are installed into the same program files folder, the application can and will crash at runtime due to version mismatches when loading assemblies.
To better understand this issue I've created this sample repo.
The dependency graph looks like this:
Library1
Microsoft.IdentityModel.Tokens-5.2.1
Executable1
System.IdentityModel.Tokens.Jwt-5.3.0 (transitive reference: Microsoft.IdentityModel.Tokens-5.3.0)
Library1
results in: Microsoft.IdentityModel.Tokens-5.3.0
Executable2
Microsoft.IdentityModel.Tokens-5.2.1
results in: Microsoft.IdentityModel.Tokens-5.2.1
To demonstrate the problem, all projects compile to the same bin folder. When the whole solution is compiled and Executable2 is started, the application crashes, since the application expects Microsoft.IdentityModel.Tokens in version 5.2.1 but the actual version is 5.3.0.
For this constructed sample it is easy to find the problem and fix it with updating the Microsoft.IdentityModel.Tokens NuGet to the same version. (Manually, since Visual Studio Package Manager does not recognize this conflict in the consolidate tab).
But at a much greater scale it is far more complex to find those mismatches.
What we have found so far
Centrally managing NuGet package versions
Since it is not yet available, it cannot be used to solve the issue here.
Microsoft.Build.CentralPackageVersions
Unfortunately there is no IDE support for it, which makes managing NuGet packages very uncomfortable, which I would like to avoid if possible.
So my question is what is the best approach to avoid NuGet version conflicts between projects within the same solution?
We've experienced the same problem with some of our projects. We've been using Paket package manager since a couple of years and this has resolved that issue for us.
In short: you define on your solution level which packages you want to use in a file called 'paket.dependencies'. You can be very specific about versions, or let packet use the latest greatest. Then you can specify per project which NuGet package you want to use within that project in a 'paket.references' file. As the name implies, you reference to a package in the paket.dependencies file.
This will make sure, all references packages in your project will use the same package version. I hope this suits your needs as well.

Versioning Issue With Local NuGet Server Packages

Some background:
At my company, I have been working the last few months with converting our C# libraries to function on .dll references instead of project to project references. To do this, we have created a local NuGet server which contains NuGet packages for all of our libraries projects. We have Jenkins jobs set up for every project which build new NuGet packages and add them to the server every time a change is made to one of them.
For working on a single project, this system works great. You only have to worry about updating your packages folder through Visual Studio's NuGet manager, and then the rest is just writing code and building.
The issue:
When you add a new reference, or update your packages through NuGet, NuGet automatically specifies that specific version of the project that you selected in NuGet. With the current system I have setup, rebuilding a project locally will then replace it's .dll in the packages folder so that all projects that reference it can see these new changes you're testing. However, the issue come in that locally built projects have a different version than our Jenkins built packages. Our local builds use a different versioning system from our Jenkins builds so that you can easily tell whether something was built using Jenkins, or if some of the .dlls came from a developer's build. Because of this different versioning scheme, the reference of projects to the project breaks, because the new .dll that was built locally has a different version than the .dll that was retrieved from the NuGet server.
Current Solution:
For the moment, I have resolved this through the addition of a pre-build step. Before every project builds, the project calls one of my PowerShell scripts, which goes through and adds <SpecificVersion>False</SpecificVersion> to every project reference in the project being built's .csproj file. This resolves the issue, but only in the sense of putting a bandaid on it. Instead of dealing with the consequences of the system, I wanted to prevent them ahead of time so that this isn't needed every time a project builds. I have tried researching a lot about NuGet packages specific versioning issues, but have not been able to find anything online even remotely close to what I am asking. This makes me think that I'm going about this wrong.
The question:
What can I do to solve this issue? Or am I doing something very wrong and dumb that could be easily avoided by using another system? Any suggestions or tips would be greatly appreciated

Adding reference of another external project in a solution

Using: .net core mvc c#
I have a solution which has a .net mvc core web app & one class library. There is a shared project (class library) that I want to this solution
which is a part of different project (different solution as well).
All of these projects are stored in our local GIT repository.
If I add the external project as project dependency in my existing project then there would be 2 copies of the external project that we have to
maintain. If some developer updates external project how does the change propogates to other projects using it.
And there could be that some developer updates the external project when under its local solution which we want to prevent. Since all are in GIT
is it possible somehow to make dependency related so that any change in external is known to others.
So basically how can we prevent anyone to make local updates to the external project but also make sure any updates to external project are available to
any other project using them.
There are several approaches that you can use to achieve this.
Quick: Reference project in two solutions
The quickest is to reference the shared project from both solutions. This way, you can use it in both projects and the changes are propagated to the other solution because you are basically working on the same files. However, a huge drawback of this approach is that if you make changes in solution A that are not compatible with solution B (e.g. removing a method that is used in solution B), you will only find out when working on solution B.
Easy: Single solution
To fix this, you could merge the solutions into a single one that contains the shared proect and also the other projects from solutions A & B. This way, you still get the convenience of project references in a solution. In addition, you are notified about breaking changes immediately if you build the complete solution. If this approach is viable for you in terms of solution size and team structure, I'd favor this approach. As you already share a single Git repository, I think this approach is well worth considering.
Nuget Package
If you want to keep the solutions strictly separated, you'd need to follow a more complex procedure. You could for instance move the shared project into a solution of its own and create a Nuget package with a clear build and versioning strategy. You can host the Nuget package on a package feed (e.g. on Visual Studio Team Services). Solutions A and B can then reference the Nuget package from the feed and also update it if a new version becomes available.
Here the official documentation to create nuget package with nuspec or csproj
Create .NET Standard 2.0 packages with Visual Studio 2017 [CSPROJ]
Creating NuGet packages [NUSPEC]

PetaPoco core .cs file not visible in ASP.NET 5 Class Library package

I am building a new project in ASP.NET 5.
In my solution I have added a new Class Library (Package) project.
I right click on this project and choose for Manage Nuget packages to install PetaPoco.Core.
When I install everything seems fine except that the PetaPoco.cs file is not in my project.
In my references I se the PetaPoco version 5.1.171 installed.
Is this something different then a normal class library and do I need to use something else in order to use the installed PetaPoco class or is it a problem during the installation?
I have removed and reinstalled this but still the same.
Someone that can help me out?
/Michael
It looks like the PetaPoco.Core package isn't setup to be used in portable class libraries (PCLs).
Including content files in PCLs like the Models folder that PetaPoco.Core creates requires a different NuGet setup than a regular project. Documentation on this can be found on NuGet. I downloaded their package directly and can confirm that it is not setup in the way the linked resource describes.
It may be that the project requires features that are not available yet cross-platform, or they simply haven't had time to make changes to support PCLs, or some other reason that I am not aware of.
NuGet packages are usually installed as DLLs in the bin folder of your project, with the needed references also added automatically to the project. They usually don't include source files. You may find sources - if available - on the package/project website.
Visual Studio IntelliSense will pick up the DLLs and show what it can about the classes and methods inside, including comments and method signatures.
See here for a tutorial, including how to build your own NuGet packages.
EDIT: PetaPoco is the exception that does add a .cs file... see comment below.

Categories