Creating a Nuget Package

Nuget

Nuget is a free and open-source package manager for the Microsoft Development Platform. It is distributed as a Visual Studio extension. Nuget client tools provide the ability to produce and consume packages. As of the writing of this article, the version of Nuget is 2.8.5. We will create a class library project containing some extension methods for a string and then will publish these extension methods as a Nuget package. Let`s get started.

Requirements

Code

To get started, open Visual Studio and create a class library project called "CSharpHelpers" using C# project template and select the target framework as .Net 4.5. Now create a folder called "StringHelpers" and add the "CustomStringHelpers.cs" file under that folder. Add the following code to the CustomStringHelpers.cs file. (Note: Make the CustomStringHelpers class as a static class since we are creating extension methods).

  1. using System;  
  2. using System.Security.Cryptography;  
  3. using System.Text;  
  4. using System.Text.RegularExpressions;  
  5.   
  6. namespace CSharpHelpers.StringHelpers  
  7. {  
  8.     public static class CustomStringHelpers  
  9.     {  
  10.         /// <summary>  
  11.         /// Remove space from the String  
  12.         /// </summary>  
  13.         /// <param name="entity">String</param>  
  14.         /// <returns></returns>  
  15.         public static string RemoveSpace(this System.String entity)  
  16.         {  
  17.             return ReplaceParticularCharacter(entity, " ", String.Empty);  
  18.         }  
  19.   
  20.         /// <summary>  
  21.         /// Remove last character from the String  
  22.         /// </summary>  
  23.         /// <param name="entity">String</param>  
  24.         /// <returns></returns>  
  25.         public static string RemoveLastCharacter(this System.String entity)  
  26.         {  
  27.             return String.IsNullOrWhiteSpace(entity) ? String.Empty : entity.Remove((entity.Length - 1), 1);  
  28.         }  
  29.   
  30.   
  31.         /// <summary>  
  32.         /// Remove first character from String  
  33.         /// </summary>  
  34.         /// <param name="entity">String</param>  
  35.         /// <returns></returns>  
  36.         public static string RemoveFirstCharacter(this System.String entity)  
  37.         {  
  38.             return String.IsNullOrWhiteSpace(entity) ? String.Empty : entity.Remove(0, 1);  
  39.         }  
  40.   
  41.   
  42.         /// <summary>  
  43.         /// Create a string from an array of string using StringBuilder class and specified separator  
  44.         /// </summary>  
  45.         /// <param name="entities">List of string</param>  
  46.         /// <param name="separator">Separator</param>  
  47.         /// <param name="trim"></param>  
  48.         /// <returns></returns>  
  49.         public static string ToString(this System.String[] entities, string separator, bool trim = false)  
  50.         {  
  51.             StringBuilder str = new StringBuilder();  
  52.             foreach (var item in entities)  
  53.             {  
  54.                 str.Append(trim ? (item.Trim() + separator) : (item + separator));  
  55.             }  
  56.             return str.ToString().RemoveLastCharacter();  
  57.         }  
  58.   
  59.   
  60.         /// <summary>  
  61.         /// Replace old character with new character in a string  
  62.         /// </summary>  
  63.         /// <param name="entity">String</param>  
  64.         /// <param name="oldCharacter">Old character</param>  
  65.         /// <param name="newCharacter">New Character</param>  
  66.         /// <returns></returns>  
  67.         public static string ReplaceParticularCharacter(this System.String entity, string oldCharacter, string newCharacter)  
  68.         {  
  69.             return entity.Replace(oldCharacter, newCharacter);  
  70.         }  
  71.   
  72.         /// <summary>  
  73.         /// Create MD5 Hash of a String  
  74.         /// </summary>  
  75.         /// <param name="entity">String</param>  
  76.         /// <returns></returns>  
  77.         public static string CreateMd5Hash(this System.String entity)  
  78.         {  
  79.             var md5Hash = MD5.Create();  
  80.             byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(entity));  
  81.   
  82.             StringBuilder sBuilder = new StringBuilder();  
  83.             foreach (byte t in data)  
  84.             {  
  85.                 sBuilder.Append(t.ToString("x2"));  
  86.             }  
  87.             return sBuilder.ToString();  
  88.         }  
  89.   
  90.         /// <summary>  
  91.         /// Convert the string to SEO friendly slug  
  92.         /// </summary>  
  93.         /// <param name="entity">String</param>  
  94.         /// <returns></returns>  
  95.         public static string ToSeoSlug(this System.String entity)  
  96.         {  
  97.             var str = entity.ReplaceParticularCharacter("&""and");  
  98.             // Remove non word characters  
  99.             Regex rgx = new Regex("\\W");  
  100.   
  101.             // Remove multiple dash characters from the string  
  102.             Regex rgx1 = new Regex("[-]+");  
  103.   
  104.             var removeMultipleDash = rgx1.Replace(rgx.Replace(str, "-"), "-");  
  105.   
  106.             var removeFirstDash = removeMultipleDash.StartsWith("-") ? removeMultipleDash.RemoveFirstCharacter() : removeMultipleDash;  
  107.             var removeLastDash = removeFirstDash.EndsWith("-") ? removeFirstDash.RemoveLastCharacter() : removeFirstDash;  
  108.             return removeLastDash.ToLower();  
  109.         }  
  110.     }  
  111. }  
Creating A Nuget Package

To create a package, first we need to create .nuspec file. This is a manifest file that uses XML to describe the package. This manifest file is used to build a package and it's also stored in the package after the package is built. To create this .nuspec file, execute the following command in a command prompt.

Nuget.exe spec

After executing the preceding command in a command prompt, we will get a success message as shown in (F:1).

Command To Create Manifest File
Command To Create Manifest File (F:1)

The default name for the manifest file is Package.nuspec. (I have created this file on my desktop and renamed the file to NugetSpec.nuspec). Copy this manifest file and add it to our class library project. Let`s open that file in Visual Studio to see the content. The contents of the manifest file are as shown in (F:2).

Content Of Manifest File
Content of Manifest File (F:2)

Now let`s go through each and every element in the file.
  • id: This is a unique identifier of the package. It's the name of the package that is used when installing the package using the Install-package command in the Package Manager console in Visual Studio. The Package Id follows the same rule as a .Net namespace. For example Mvc.Helper is a valid package id.

  • Version: This is a version of the package like 1.0.0.

  • Authors: This is a comma separated list of the authors of the package.

  • owners: This is a comma separated list of package creators. Most of the time it is same as package authors.

  • licenseUrl: This is a link to the license that the package is under. For example Apache license.

  • projectUrl: This is a link to the project home page. If the project is open-source then it can be the project source code URL like Github project URL.

  • iconUrl: This is the link for the image that is used as an icon for the package. The size of the image should be a 32x32 pixel png image with transparent background.

  • requireLicenseAcceptance: This is a boolean value that indicates whether the Nuget client must ensure that the package license (specified by licenseUrl) is accepted by the user before installation of the package.

  • description: As the name suggests, this is a long description of the package.

  • releaseNotes: This is a description of the changes that are made in each release of the package.

  • copyright: Specify copyright details for the package.

  • tags: This is a space-separated list of keywords that describes the package. These tags are useful when a user tries to search for the package.

  • dependencies: This element specifies the list of other dependent Nuget packages that should be installed in order to use our package.

  • title: This is a user-friendly name of the package. If not specified then the package id is used. (By default this element is not included in the manifest file.)

  • files: This element is used to specify the package content. (By default this element is not included in the manifest file.)

Now let`s fill in the details in package manifest file. The contents of the updated manifest file are as shown in (F:3).

Updated Manifest File Content
Updated Manifest File Content (F:3)

Note: The source code for this example is added to my Github repository. I am using my Github project URL as the project URL in the manifest file. I have also added the License document to the source code.

Nuget Package Content

The contents of the Nuget package can be defined either by defining a conventional based folder structure relative to the package manifest file or by using a files element in the manifest file. The convention based approach requires the following folder structure:

  • tools: The tools folder of a package is for PowerShell scripts and programs accessible from the Package Manager Console.

  • lib: Assemblies (DLL files) in the lib folder are added as assembly references when the package is installed.

  • content: Files under the content folder are directly copied to the root of the application when the package is installed. For example, if we want to add a script file to the /Scripts folder of the target application, then we need to place that file under Content/Scripts/{jsfilename}.

Now first let`s create the package using the Convention based approach, then we will see how to create the package using the files element in the manifest file.

Convention Based Approach To Create Nuget Package:

To create package using the Convention based approach, create a new folder called "CSharpHelpersPackage" tehn add the manifest file that we created in the early steps under that folder. In order to use our extension methods, we need to add reference of our DLL in target application. For that purpose let`s create a new folder called lib and add our class library project DLL (CSharpHelpers.dll) under that folder (Note: Be sure to copy the DLL from the bin/Release folder). Let`s also add a read me file to specify the extension methods included in our package. This file will open up after installation of the package in the target application. The contents of the CSharpHelpersPackage folder are as in (F:4).

CSharpHelpersPackage Directory Content
CSharpHelpersPackage Directory Content (F:4)

Now it's time to create the package. To create the Nuget package, execute the following command in a command prompt.

Nuget.exe pack NugetSpec.nuspec

After execution of the preceding command in a command prompt, we will get a message as shown in (F:5).

Nuget Package Creation Using Convention Based Approach
Nuget Package Creation Using Convention Based Approach (F:5)

According to the message, the Nuget package is created successfully but there is the warning "Assembly not inside a framework folder". The solution to resolve this warning is also provided in the same warning message, that we need to move the assembly into a framework specific folder.

When we install a Nuget package, it determines the framework of the target application and then tries to find the appropriate assembly under the lib folder. When creating our class library project, we selected the target framework as .Net 4.5, so create a new folder called net45 under the lib folder and move the CSharpHelpers.dll to inside the net45 folder. net45 is the abbreviation for the .Net framework 4.5. For more information regarding the common framework and their abbreviation click here. Now let's try to create the package one more time. Now this time, after execution of the command, we will get a success message as shown in (F:6).

Created The Nuget Package Using Convention Based Approach
Created The Nuget Package Using Convention Based Approach (F:6)

Great! We are able to create a Nuget package using the convention based approach. Now let`s try to create a package using a files element in the manifest file.

Create Nuget Package Using files Element In Manifest File

To create the package using the files element in the manifest file, add the following code to the manifest file after the metadata element.

  1. <files>  
  2.    <file src="bin\Release\CSharpHelpers.dll" target="lib\net45"></file>  
  3.    <file src="readme.txt" target=""></file>  
  4. </files>  
The Files element in the manifest file is just the other way of specifying the contentd of the Nuget package. Execute the same command (Nuget.exe pack NugetSpec.nuspec) to create the Nuget package. We will get the same success message as shown in the image in (F:6).

Testing

This is a very important step. We need to be sure that after installation of the package in the target application, our package contents are being placed at the proper place. To test the Nuget package, we can create a local feed of Nuget packages in Visual Studio. To create a local feed, create a new folder called MyLocalFeed on any drive. (You can name the folder as you like. I have created the folder on my E: drive.) Then add the Nuget package that was created earlier to this folder. Now to add this local feed in Visual Studio, open Visual Studio then go to Tools => Options. Then search for the Package Sources option. It will be under the Nuget Package Manager option as shown in (F:7).

Creating Local Feed Of Nuget Package In Visual Studio
Creating Local Feed Of Nuget Package In Visual Studio (F:7)

To add a local feed, click on the plus icon. It will add a new package source named "Package Source" and the source value as "http://packagesource" as shown in (F:8).

Create New Local Nuget Package Feed
Create New Local Nuget Package Feed (F:8)

Rename the package source as "Local Feed (You can name the source as you like)" and replace the default source value with the path to our local feed folder as shown in (F:9).

Local Nuget Package Feed Configuration
Local Nuget Package Feed Configuration (F:9)

After filling in the details, click on the Update button. After clicking on the Update button, our local package feed will be listed in the Available package sources as shown in (F:10).

Local Feed Is Added As Package Source
Local Feed Is Added As Package Source (F:10)

Now to test our package, create a new console application. Right-click on References and select the Manage Nuget Packages option from the menu. It will open the Manage Nuget Package window. Select the online option from the left menu. Under the Online option, our Local Feed (here Local Feed is the name of the package source that we have specified when configuring the local Nuget package feed) will be displayed as a package source as shown in (F:11).

Install The Nuget Package
Install The Nuget Package (F:11)

As shown in the image in (F:10), we can see our Nuget package CSharp Helpers is listed under the Local Feed. Now click on the Install button to install the Nuget package. After installation of the package, CSharpHelpers.dll will be added as an assembly reference to our console application as shown in (F:12).

Added As An Assembly Reference
CSharpHelpers.dll Is Added As An Assembly Reference (F:12)

Now the next step is to test the extension methods included in our package. Add the following code to the Program.cs file.
  1. using System;  
  2. using CSharpHelpers.StringHelpers;  
  3.   
  4. namespace ConsoleApplication1  
  5. {  
  6.     internal class Program  
  7.     {  
  8.         private static void Main(string[] args)  
  9.         {  
  10.             var str = "How to create a nuget package";  
  11.             Console.WriteLine(str.RemoveSpace());  
  12.             Console.ReadKey();  
  13.         }  
  14.     }  
  15. }  
The preceding code uses the RemoveSpace extension method to remove the space from the str variable. Now let's run the application to see the output. The output is as shown in (F:13).

output
Output Of Console Application (F:13)

As shown in the preceding image, spaces are removed from the string variable. Great! We are able to create and test our Nuget package successfully.

Conclusion

In this article, we learn how to create a Nuget package and test it by creating a local feed of Nuget packages. I hope you enjoyed reading the article.

Happy coding.


Similar Articles