Create a NuGet package
Table of Contents
Whether you are working alone or in a company, duplicating code is never a good practice. It is one of the first rules in computer science: when you create something, you reuse it, consolidate it, but avoid recreating it, except in rare cases.
Our goal here is to create reusable libraries that can be easily integrated into any project or other library.
We will not address the issue of code obfuscation here. Every NuGet package we create, containing DLLs, will potentially be readable by anyone. We will discuss code obfuscation in another article.
To simplify, we will see how to create a NuGet library from C# code and publish it on GitHub.
This will allow you to integrate your libraries very easily using NuGet, just as you already do for any open-source library used in your various projects.
Code Breakdown #
Before diving into the heart of the matter, let’s take a little detour. Creating a NuGet package involves creating a library. This library will contain code, code that will evolve and might also have its own dependencies.
I strongly encourage you to structure your code well, following the standard separation found in .NET: an abstraction library and an implementation library, such as:
- MyLib.Abstractions
- MyLib
The abstraction library will contain all the interfaces necessary for the proper functioning of your implementation library, but without knowing the details. This implementation will be reserved for the second library. Don’t worry, we will see right after a method to publish one or more libraries without any problem.
To illustrate this point, here is a diagram representing an example of a library divided into several sub-libraries, thus respecting the separation of roles (SOLID principle), notably the separation of interfaces and implementations:
Let’s now take an example of a library you must know: Microsoft.Extensions.Logging. There are several of them, each having their role and notably, in our example, Microsoft.Extensions.Logging.Abstractions. We can clearly see the interfaces separated from the implementations:
We can see here that the implementations Logger
Of course, the library Microsoft.Extensions.Logging references Microsoft.Extensions.Logging.Abstractions as a dependency in this case. It will be the same for our own libraries.
Creating NuGet Packages #
Creating NuGet packages is relatively simple. Thanks to the .NET CLI, you can generate all your NuGet packages locally or on your CI very easily.
As you will understand, most of the necessary instructions will not be done directly in the code. They will be executed via the terminal or console with .NET commands.
For more practicality and scalability (local use and on a CI), I suggest using a batch script allowing the automatic execution of NuGet package generation:
while getopts v:k: flag
do
case "${flag}" in
v) version=${OPTARG};;
k) key=${OPTARG};;
esac
done
dotnet pack "MyLib.csproj" --configuration Release
dotnet pack "MyLib.Abstractions.csproj" --configuration Release
This script is relatively simple:
- It retrieves the version and key to use as input parameters (we do not want to hardcode the key for security reasons)
- It uses the dotnet pack command for each library
Publishing on GitHub #
Remember that it is quite possible to use your NuGet packages locally. You do not need to publish them on a server (GitHub or others) if you are working alone or in a small team that does not wish to invest in a server.
However, in this guide, we will see how to share our libraries privately within our organization, so that everyone working with us can use them.
Fortunately for us, GitHub offers all the necessary features for this.
To start, go to your GitHub account settings. Then go to “Developer settings”, then “Personal access tokens” and finally “Tokens (classic)”.
We will now create a new token. It will need at least the following permissions:
- delete:packages
- repo
- write:packages
As you will understand, it is necessary to save the new key generated. If you don’t want to have problems later: unable to publish, someone else published in your place, etc…
We will now modify the previous script to manage automatic publishing on GitHub:
dotnet nuget push "MyLib/bin/Release/MyLib.$version.nupkg" --api-key $key --source "myNuget"
dotnet nuget push "MyLib.Abstractions/bin/Release/MyLib.Abstractions.$version.nupkg" --api-key $key --source "myNuget"
The dotnet nuget push command allows this publication. Note that we use the –source parameter with this command. It allows defining the deployment target. In this case, it is our GitHub server.
But before running our script again, it is important to explain to NuGet what myNuget represents. To do this, add the nuget.config file to the root of your project:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="myNuget" value="https://nuget.pkg.github.com/MyTeam/index.json" />
</packageSources>
<packageSourceCredentials>
<github>
<add key="Username" value="MyUsername" />
</github>
</packageSourceCredentials>
</configuration>
You can now run the script again and see your library directly on your GitHub account!
So now how to use them?
Using a Custom Library via NuGet #
For those unfamiliar with NuGet, it works similarly to Maven and other well-known dependency managers on various platforms. In other words, there are main servers managed by large companies and automatically used by different development environments (IDEs). However, it is quite possible to add our own sources and configure our own NuGet servers.
We will therefore add a new data source to our IDE. Here are configuration examples for the two main IDEs.
With Visual Studio #
With Visual Studio it’s very simple. Go to the “Options” > “NuGet Package Manager” settings and click on “+”
From there, you just need to enter the required information and you’re done! In the NuGet package manager, you will see your new source:
With Rider #
When you open your NuGet dependencies manager in Rider, go to the “Sources” tab. It will offer you a default list of available configurations:
- [Effective NuGet.Config]
- And your own configuration
It is in the latter that we will add a new source. Select it and click on the “+” button.
You can now directly see your libraries in your NuGet manager:
In conclusion, creating and sharing NuGet packages can greatly facilitate dependency management and code reusability, whether you are working alone or in a team. By following these steps and adopting good practices, you can optimize your workflows and improve collaboration within your organization.
Hoping you enjoyed this article, feel free to share it and come!