# How YOU can create reusable packages for .NET Core using VS Code, C# and NuGet
Follow me on Twitter, happy to take your suggestions on topics or improvements /Chris
Creating a reusable package of code is great. It allows you to be faster up and running next time you are about to build something. It can also help your colleagues or why not the entire planet if you upload your package to a publically available repository.
For .NET (including .NET Core), the Microsoft-supported mechanism for sharing code is NuGet, which defines how packages for .NET are created, hosted, and consumed.
So NuGet is an open-source package manager designed for the Microsoft development platform and was introduced in 2010.
Sweet, is there a lot of packages somewhere out there ready for me to use?
Yes, they all reside here:
https://www.nuget.org/
You can also add the package to your project through a simple command in the terminal or using a UI if you have a full-blown IDE like Visual Studio, for example.
Let's learn how to create such a package, a so-called nuget for .NET Core, using VS Code. Let's also get it up there at https://www.nuget.org
so everyone else can enjoy it as well.
In this article we are looking to go through the following:
- Why create a package. It's important to know why we are creating a package as opposed to just creating a library for example.
- Creating a library, here we will create a library, add some code and some tests. You should always test to your code.
- NuGet package creation, here we will create a NuGet by using a terminal command
- Install your package locally, we want to ensure that our package works locally. We can easily do that by installing it to one of our existing projects.
- Publishing your package to NuGet repository for anyone to try out. We will need to get some credentials to NuGet to be able to do this step but then it's literally just one command.
Resources
Here are some important resources you might need to further extend your knowledge on .NET Core.
Why create a package
Ok, so you want a package. Do you know why you want one? A lot of the times creating something reusable means creating a library. You might be a program vendor or you might be an OSS developer though or you got another good reason. Using NuGet to distribute your code means that anyone on the planet can use your code.
Are you:
- intellectually curious how this is done in .NET Core?
- do you want to create something reusable that you want anyone to access and install?
If the answer is yes to any of the above you seem ready to learn.
Stay with me young Padawan, we are about to learn a lot.
Creating a library
The package is meant to be something reusable, like a library that we can add a reference to in our existing project. Because we are using .NET Core for this, we will be using the terminal. We will do the following:
- Create a solution directory for our solution to live in
- Create the solution file itself
- Create a class library type project
- Add the class library reference to the solution
Create a solution directory First, let's create a directory, remember, you can name this whatever you want.
mkdir example
cd example
2
Create a solution file Thereafter we will scaffold a solution file by using the following command:
dotnet new sln
It should say something like so:
Create a class library Next we will create the class library. This is where our reusable code will live.
dotnet new classlib -o library
Add the class library to the solution We should add this class library to the solution. This will give us the ability to build everything at once among other benefits.
dotnet add sln add library/library.csproj
This should produce the following:
Add some code and tests
Ok, we have a solution, a class library, but we are missing the meat, the code we want the world to use.
Let's open up our solution and add some code.
Rename our Class1.cs
file to Start.cs
. Now let's replace whatever code is in there with this:
namespace library
{
public class Start
{
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Behold, the most impressive calculator known to man. 😉
Adding tests We need to have tests for this, cause we are professionals.
Let's start by creating a test library
dotnet new xunit -o library.testing
Next, we need to add a reference to our library project so we can test the code. So we type :
dotnet add library.testing/library.testing.csproj reference library/library.csproj
This should add a reference to our test project. Next let's author a test.
Rename test file UnitTest1.cs
to Test.cs
. What you name doesn't matter, it's just nice if you give it a meaningful name.
Ok, for the tests, replace your code with the following:
// Test.cs
using System;
using Xunit;
using library;
namespace library.testing
{
public class Test
{
[Fact]
public void TestingAdd()
{
var start = new Start();
var actual = start.Add(1, 2);
Assert.Equal(3, actual);
}
[Fact]
public void TestingSub()
{
var start = new Start();
var actual = start.Sub(1, 2);
Assert.Equal(-1, actual);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Next head to the terminal and type:
dotnet test dotnet test library.testing/library.testing.csproj
It should render in the following result:
Good, we are ready for turning this into a NuGet package now that our code looks like its working.
Create a NuGet package
We need to do the following to create a NuGet package:
- Add some meta information to the library project
- Invoke the
pack
command, this will create the package
Adding meta information
Now this is about adding meta data information to your project. Meta information are things like name, author, company and so on. You will need to add this as entry in the library.csproj
file under the XML tag PropertyGroup
. It can look like this:
<TargetFramework>netcoreapp2.2</TargetFramework>
<PackageId>math-chris</PackageId>
<Version>1.0.0</Version>
<Authors>chris_noring</Authors>
<Company>happy coder inc</Company>
2
3
4
5
The PackageId
+ Version
will determine the name of your package. Next let's create our package. Let's navigate to our library directory and type:
cd library
dotnet pack
2
We can see from the above image that we got a package created in the bin/Debug
folder called math-chris.1.0.0.nupkg
.
We will use this information in our next section where we learn to install the package locally.
## Install your package locally Let's start with the WHY? We need to test the package locally before we can push it nuget.org, that's just using sound judgment, we don't want to push anything broken.
So how do we do this? Well, we need a project to test it on. Let's scaffold a console application
dotnet new console -o app
Let's add it to the solution:
dotnet sln add app/app.csproj
Next, lets now install our package. We do this in two steps:
Point out the local source, this is about instructing the target project where this package can be found on your computer, so if it fails to find it on NuGet it knows to look at your computer next.
Add the package, this will install the package in the target project
Point out the local source
We need to go into the target projects .csproj
file. We want to test out our NuGet package on our console app called app
so we open up app.csproj
and under PropertyGroup
we add a tag called RestoreSources
. Here we point out both the path to our local NuGet package and the NuGet stream. It should look like so:
<RestoreSources>$(RestoreSources);absolute-path-to-my-solution/library/bin/Debug;https://api.nuget.org/v3/index.json</RestoreSources>
You need to replace absolute-path-to-my-solution/library/bin/Debug
above with the absolute path to where your package is located.
Add the package
Now that we pointed out where NuGet can find our package we are ready to install it.
This is as simple as calling (from the solution root):
dotnet add app package math-chris
math-chris
is the name of the package we give it in the meta tags.
Inspecting our app.csproj
file we can see that we now get the following entry:
<PackageReference Include="math-chris" Version="1.0.1" />
Now lets try out our installed package. Change Program.cs
in your app project to the following code:
using System;
using library;
namespace app
{
class Program
{
static void Main(string[] args)
{
var start = new Start();
Console.WriteLine(string.Format("Hello World! {0}", start.Add(2, 2)));
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Working with different versions
As an author of a NuGet package you probably want to update your library sooner or later and add more functionality or correct bugs. Depending on what kind of update you do - you should increment the version number differently. Let's look at the version numbers in general and talk about a concept semantic versioning:
1.0.0
The leftmost value is called a major version. This should only be incremented if we do really major changes, including breaking the interface like, removing or renaming code. Updating it means we go from 1.0.0
to 2.0.0
.
The middle value is called a minor version. You use this when you do things like adding more functionality, like adding more methods. Updating it means we go from 1.0.0
to 1.1.0
.
The rightmost value is called a patch version. You should use this to do small changes. Those types of changes are usually because you want to fix an error, i.e patching the code. Updating it means we go from 1.0.0
to 1.0.1
Upgrading
Ok, so you've decided on upgrading your package. That means that you will need to take the following steps:
- Add new functions to our library project
- Increment the minor version of the package
- Generate a new NuGet package from our library project
- Install the new version on our console project
app
Add new functions
Let's go to our library project. We will add code to handle multiplications, like so:
public int Multiply(int a, int b)
{
return a * b;
}
2
3
4
the code in Start.cs
should now look like so:
using System;
namespace library
{
public class Start
{
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
public int Multiply(int a, int b)
{
return a * b;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Increment the minor version
Open up library.csproj
and find the XML tag Version
and make sure it looks like this:
<Version>1.1.1</Version>
Generate a new NuGet package
For this, we will navigate ourselves to the library directory and run dotnet pack
.
This should create the file math-chris.1.1.1.nupkg
Install the new version
To install the new version we need to open up our app.csproj
and increment the version. We need to find the XML tag PackageReference
and change the attribute Version
to 1.1.1
like so:
<PackageReference Include="math-chris" Version="1.1.1" />
Thereafter we can run dotnet restore
in our app directory.
Your terminal should say something like this:
Installing math-chris 1.1.1
This means that you got the new code. Let's ensure that is the case by testing it out. Remember, you should have access to the Multiply()
function. Open up the Program.cs
file and change the code to the following:
using System;
using library;
namespace app
{
class Program
{
static void Main(string[] args)
{
var start = new Start();
var result = start.Multiply(2,2);
Console.WriteLine(string.Format("Hello World! {0}", start.Add(2, 2)));
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Managing versions
Sometimes you have the following scenario:
- Fix a mistake, You produced a package but realize you made a mistake in the code that you want to fix AND you want to stay on the same version
- Go to a lower version, You want to move back to a previous version of the package
In both these cases, you need to deal with your local NuGet cache. The way it currently works is that you can always increment a version and do a dotnet restore
. Going back means you need to clear the cache first, as it would otherwise hold on to the newest version. You do that by the following command:
dotnet nuget locals all --clear
Now you can change Version
attribute to a lower one in app.csproj
and go to the terminal and your app directory and do dotnet restore
. Your code, in Program.cs
, should now be yelling at you saying you don't have a Multiply()
method and that's a GOOD thing, it means the whole process is working as it should.
Remember, you can always change the Version
back to 1.1.1
do a dotnet restore
and your code will work fine again 😃
## Publishing your package
Ok, we spent a lot of time talking about testing your package locally. As interesting, and important, as that is, we want to publish it to the great NuGet repository in the Sky nuget.org.
How do we do that?
you need the following:
- NuGet credentials
- Invoke the
publish
command
Create an account
This is a pretty quick thing. Go to nuget.org and enter an email and username and password. Once all that is done you need to create a key. You do that by clicking at your username, at the top right corner of the page. Then you select API Keys
.
On the page click the + Create
and fill in Key Name
and on Selected Scopes
check Push
. On the field Glob Pattern
just enter a *
. The last step is clicking the blue Create
button. Scroll down the manage now and find the Manage
section. Your new key should exist here. Press the Copy
button and your key should now be in your clipboard.
Invoke the publish command
Now we have come to the fun part. We've built our package. We've obtained a key and we are one command away from pushing our package to nuget.org.
The command we need looks like this:
dotnet nuget push [package name].nupkg -k [API key] -s https://api.nuget.org/v3/index.json
Place yourself in the library/bin/Debug
directory, replace with your values above and run the command in the terminal.
You should get a response looking like this:
You should now find your package at:
https://www.nuget.org/packages/math-chris/1.1.2
Remember though. Your package doesn't do much. At least improve it from this point on. If it's useful for you it's gonna be useful for someone else 😃
Summary
We've come to the final stop. Time to recap what we've learned. We've managed to learn:
- Why a package might be a good thing to create
- How to create a package
- How to test the package locally
- How to push the package to nuget.org
Hopefully, this will make you inspired to create packages of your own 😃
Go, go out there and create, there is no try