NuGet Made Easy: Create Your Own NuGet Package

by Kenji Elzerman
The Power Of NuGet Create Your Own Package - Kens Learning Curve

A while ago I wrote about hosting NuGet packages on your own, private feed with Azure DevOps Artifacts. This raised the question: How to create your own NuGet package? To create a NuGet package you need a few things: Code and some settings. In this article, I am going to show you how easy it is to create and upload your NuGet package.

Goals

Although this article talks about it, I am not explaining to you how you can create a NuGet feed in Azure DevOps. This article shows you how you can create a NuGet package through Visual Studio and push that package into a feed.

So, after this article you:

  • Can create a simple NuGet package using Visual Studio
  • Know where you can find the settings for the NuGet package
  • Understand the basic layout of a package
  • Can upload (push) a package to a feed

A Class Library

Let’s start with creating a basic C# class library. This will be the code we will store in our NuGet package. I am going to create a C# Class Library, using .NET 7, and I call the project KLC.Extensions. The scaffolded class will be renamed to StringExtensions.cs, and the class will get the same name. The contents of the class will be this:

using System.Text.RegularExpressions;

namespace KLC.Extensions;

public static class StringExtentions
{
    public static string MakeUrlFriendly(this string text)
    {
        return text
            .Replace(" ", string.Empty)
            .Replace("#", string.Empty)
            .Replace("?", string.Empty)
            .Replace("&", string.Empty)
            .Replace(";", string.Empty)
            .ToLower();
    }

    public static string TrimAndReduce(this string value)
    {
        return ConvertWhitespacesToSingleSpaces(value).Trim();
    }

    public static string ConvertWhitespacesToSingleSpaces(this string value)
    {
        return Regex.Replace(value, @"\s+", " ");
    }

    public static int WordCount(this string text)
    {
        return text.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
    }
}

Just some examples I randomly found on the internet.

Make It A Package

The class library builds and, if we do it 100% right, the unit tests are built and all succeed. (yes, I don’t have unit tests, but you should make them). All we need to do now is create the NuGet Package.

In the past, we had to construct a package on our own because a NuGet package is just a zip file with a certain folder structure. Then we got the NuGet Package Explorer, but it’s not really supported anymore. The reason the NuGet Package Explorer is out of commission is that Visual Studio has everything we need. It’s just a setting.

To create a NuGet package, simply open the properties of the project you want a package of. You do this by right-clicking the project and selecting “Properties”.

Project Properties - The Power Of NuGet Create Your Own NuGet Package - Kens Learning Curve

A new screen is shown with all the properties of the project. On the left, you see a navigation. Click on Packages. Here you will have everything you need to create a NuGet package.

Project Properties Package - The Power Of NuGet Create Your Own NuGet Package - Kens Learning Curve

All you have to do is check the Produce a package file during build operations. But this screen has way more options and settings. Each setting has a good description of the name, which is self-explanatory. You can use variables in some settings and when you do, the preview is shown under the setting.

For example the Company. This is, by default, the project name. The name is stored in the variable $(Authors), But you can change it to whatever you like.

If you made a mistake you can press the gears-icon which appears when you hover over a setting. This gives you a few options. One of them is Reset property to default value.

Reset Property - The Power Of NuGet Create Your Own NuGet Package - Kens Learning Curve

Package Created

Let’s rebuild the solution. Yes, only the project would be enough, but I like to be thorough. When it’s done building, check out the Output window.

Package Created - The Power Of NuGet Create Your Own Package - Kens Learning Curve

Maybe it is a bit hard to read, but you can see that it has created a package on D:\POCS\KLC.Extensions\KLC.Extensions\bin\Debug\KLC.Extensions.1.0.0.nupkg.

You can copy, paste, and edit this location in File Explorer, but you can also right-click on the project and select Open Folder in File Explorer. This opens the file explorer and the location of the project. Then go to bin -> Debug. And there is the NuGet Package.

It’s Just A Zip File

Now open the package with WinZip, 7Zip, WinRar, or whatever tool you have to open archives. You can just take a peek inside the package and see the construction.

NuGet Package Opened In Zip - The Power Of NuGet Create Your Own Package - Kens Learning Curve

The .nuspec file contains all the information a NuGet Package needs. These are the settings you can change in the Package properties of the project. You can open this file in Notepad(++) if you are interested.

The lib folder contains the actual DLLs and other files you created. My NuGet Package only contains one DLL. If you want to support different .NET versions, you can add them here.

The other folders and files are configuration settings and not really important to mention.

You can add or modify the NuGet Package if you want, but I highly recommend using Visual Studio for this.

Pushing The Package

Now it’s time to push the package to the NuGet feed. This could be the public NuGet.org or your own private repository in Azure DevOps for example. I will be using the latter.

We need to use dotnet.exe to upload packages. Open a command prompt and browse to the folder that contains the NuGet package you just created. Or, alternatively, you can use File Explorer and type ‘cmd’ in the address bar and press enter. This will also open a command prompt but on the location of the File Explorer.

Now paste the command line you just copied and change it accordingly:

dotnet nuget push KLC.Extensions.1.0.0.nupkg --api-key qz2jga8pl3dvn2akksyquwcs9ygggg4exypy3bhxy6w6x6 --source https://pkgs.dev.azure.com/infoklc/NuGetDemo/_packaging/DemoFeed/nuget/v3/index.json

You already have the dotnet.exe since it comes with the installation of Visual Studio and the .Net SDK. But this will give an error:

Error: Unauthorized

If you have never pushed a package before, you might run into an error:

Response status code does not indicate success: 401 (Unauthorized).

This is because your system doesn’t have the right credentials and authorization to push something to your feed.

On the page of your Connect to feed, with the dotnet selected, there is a button Get the tools. Click this one and you see two steps. You can skip the first step because you already have the .NET Core SDK. But the second step is important. Click this one.

Azure DevOps Connect To NuGet Feed Get The Tools dotnet - Set Up A Private NuGet Repository In Azure DevOps - Kens Learning Curve

This will bring you to a GitHub repository managed by Microsoft. Download the code to your hard drive. I’ll wait…

Extract the zip you just downloaded and open PowerShell. Go to the folder that you just extracted and go to the folder Helpers. Execute the ./installcredprovider.ps1. If you are unlucky, like me, you will get an error:

installcredprovider.ps1 is not digitally signed. You cannot run this script on the current system. For more information about running scripts and setting execution policy, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.

This means you don’t have the right to execute this script since it wants to place files in a system directory or profile directory. We need to give it access first.

(just remember: This has to be done one time)

Luckily this is an easy one because I am just going to tell you which command you need to execute. While you are still in the PowerShell command, execute the following command:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

After executing this you won’t see a thing, but stuff happened… Trust me. You can now execute PowerShell commands.

Note: If you are on a corporate laptop/desktop, this might not work. Simply because your IT department might have disabled changing the execution policy. You might want to ask your IT person to lift it or set the policy for you. Nothing I can do from here if that happens.

Try To Push Again

Execute the ./installcredprovider.ps1 again. It will now install the Credential Provider on your system. Remember that you need to do this again if you switch to a different system… ONLY if you want to publish.

Let’s try to publish the package again. Still an error about an unauthorized attempt! We do have the credential provider installed, but we need to log in. We can’t log in using the command line, but we can make it work with a login system.

Execute your command to publish the package, but add –interactive behind it:

dotnet nuget push KLC.Extensions.1.0.0.nupkg --api-key qz2jga8pl3dvn2akksyquwcs9ygggg4exypy3bhxy6w6x6 --source https://pkgs.dev.azure.com/infoklc/NuGetDemo/_packaging/DemoFeed/nuget/v3/index.json

If you run it now, dotnet.exe will pause.

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code GV6PVEHUA to authenticate.

Don’t wait too long, but open the browser and paste in the code. Next, you need to log in with an account that has access to the feed (aka your project). Fill in the credentials and accept that you are trying to login into Artifacts. It could take some seconds, but eventually, dotnet.exe will continue and your package will be uploaded.

Your NuGet package is now in the feed and you can use it and find it through the NuGet Package Manager in other projects.

Conclusion On Create Your Own NuGet Package

As you can see it’s just a checkbox that needs to be checked to create your own NuGet package. You can change some basic settings and you are set to go.

One of the biggest downsides, in my opinion, is the fact Visual Studio can’t push the package to the feed. You can create a package, but not upload it. You have to do this by using a command prompt (or the NuGet Package Console if you are feeling adventurous). Maybe it’s a good idea to create an extension for this?

Table Of Contents
Kens Learning Curve