Appendix G

Visual Studio Extensibility with NuGet

Over the years, the community of .NET developers has developed a large number of reusable libraries and utilities to help accomplish common tasks. Many of these third-party reusable libraries have found their way into the .NET developer’s primary toolbox. In addition, .NET has become a thriving platform for open source development. Some of the most popular libraries have been published as open source projects.

In all aspects of .NET development, reusable libraries, whether open source or not, have become a valuable source of functionality. This fact is never more evident than in web development where the use of third-party .NET and JavaScript libraries is commonplace. In fact, many of the project templates in Visual Studio include third-party libraries.

Incorporating these libraries into your project can be as simple as including references to one or more assemblies. But more often, it is not as straight forward. If you don’t already know the particular library that will give you the desired functionality, you need to find one. Once you have found a particular library, you need to download it. Often you have to choose the correct download from multiple versions or options. Don’t forget to unblock the ZIP file after downloading the correct one. You should really verify the file using the hash provided by the download page. You then need to unzip the file into a folder within your solution. Often you create a lib folder to unzip the files into. You need to add a reference to the newly unzipped assembly or assemblies from within the Solution Explorer in Visual Studio. Now begins the process of setting the correct configuration settings in the app.config or web.config file and writing any initialization code required by the library. Determining the correct configuration settings often requires reading the documentation or researching forums and blogs.

As these libraries are developed, they incorporate and rely on other libraries, which in turn potentially need to be configured. The more dependencies, the more configuration headaches.

NuGet is a Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects that use the .NET Framework.

NuGet allows developers who build libraries to “package” their library and store it in a repository that makes it easy for others to find. The package, a .nupkg file, includes everything needed to install and configure the library in a solution. All the packages in a repository are bundled into feeds that can be accessed on the NuGet website or directly through Visual Studio. Developers who are looking for a library can search the feed and install the package through a command-line interface or a graphical interface.

USING NUGET IN VISUAL STUDIO

Prior to Visual Studio 2012, NuGet was installed using the Visual Studio Extension Manager. However, the NuGet client is already installed in Visual Studio 2012. In order to verify you have NuGet installed and to install NuGet if necessary, you can use the Visual Studio Extension Manager. Figure G-1 shows the Extension Manager in Visual Studio showing the extensions that are currently installed.

FIGURE G-1

image

The Extension Manager is also used to update NuGet when new versions are available. If an update is available for NuGet, you can see it in the Updates tab of the Extension Manager. Figure G-2 shows the Extension Manager displaying an update for NuGet. The update can be installed directly from this same interface.

FIGURE G-2

image

Once NuGet is installed, you can find, install, and manage packages using either the Manage NuGet Packages window or using PowerShell commands in the Package Manager Console.

Managing NuGet Packages with the Window

The NuGet client for Visual Studio provides a graphical interface by way of the Manage NuGet Packages window. In order to use the interface, you need to have a solution loaded into Visual Studio. For the purpose of this example, create a new ASP.NET MVC 4 Web Application project and select Internet Application as the template type. In order to open the Manage NuGet Packages window, right-click on the project and select Manage NuGet Packages. Figure G-3 shows the Manage NuGet Packages window.

FIGURE G-3

image

Notice that there are already many packages loaded. Many project templates in Visual Studio also use NuGet packages to include certain third-party and open source libraries in a new project. As seen in Figure G-3, the left side of the window contains tabs that allow developers to see not only the currently installed packages, but also packages that are available to be installed. You can also see if any installed packages have updates.

Click on the Online tab to see the packages available to be installed. Figure G-4 shows the window with the Online tab selected.

FIGURE G-4

image

There are a few things to make note of in Figure G-4. This first thing to mention is there are some packages in the list that have green checks in the upper-right corner of the package item. The checks indicate that the package is already installed in the current project. When a package is available to be installed, highlighting the package causes an Install button to appear. Highlighting a package also displays more information about the package in the right pane of the window.

NuGet packages are published to NuGet repositories. The repositories bundle the packages into a feed, which is what is ultimately displayed in the list of available packages. These repositories are called package sources. In Figure G-4, you can see that there is one default package source available under the Online tab. The default package source is hosted by Microsoft and is given the name “NuGet official package source.” It is possible to add additional package sources. You can enable and disable package sources as well. This allows you to temporarily prevent a package source from showing in the list without having to delete it. In order to modify package sources, you will need to go into the Package Manager’s settings. Click the Settings button in the lower left of the Manage Packages window to open the Options window. Figure G-5 shows the Options window with the Package Sources settings selected.

FIGURE G-5

image

In order to add a new package source, enter a name for the package source and its source URL. Note that you can also enter a folder path for the source. A folder containing NuGet packages is considered a valid package source. Different types of package sources are covered later in this appendix. Figure G-6 shows the Options window after adding a sample NuGet package source hosted by Phil Haack. The new package source is named Haacked Sample.

FIGURE G-6

image

After you close the Options window, the feed in the Manage NuGet Packages window is refreshed. Now it includes the packages from the Haacked Sample package source. By default, all of the packages from all of the enabled package sources are shown in the list and, if necessary, can be paged through. You can select a single package source to show only its packages. Figure G-7 shows the packages available only from the Haacked Sample package source.

FIGURE G-7

image

Installing a NuGet Package

Installing a package is as simple as clicking the Install button on the package. But what really happens when you install a NuGet package? In order to see some of the changes a NuGet package makes when installed, find the package for the ELMAH.

ELMAH enables application-wide error logging for ASP.NET web applications. It is a good example because it has other dependencies and requires changes to the web.config file to configure it. From the Manage NuGet Packages window, use the search box to search for ELMAH. Note that you can also search for “logging” or “error logging” and find ELMAH in the search results. So you can search for content as well as the name of a package, which can be helpful if you don’t know the name of a package but know what functionality you need. Figure G-8 shows the results of searching for ELMAH.

FIGURE G-8

image

Clicking the Install button will start the download and installation of the package. One of the additional things that happens when you install a package is that any packages it depends on are also downloaded and installed. As an example, Figure G-9 shows the installation window that is displayed during the download and installation process.

FIGURE G-9

image

Notice the dependency on a version of elmah.corelibrary greater than 1.2.2. The package ELMAH depends on, called elmah.corelibrary, is also downloaded and installed. You didn’t have to do anything special to get this to happen. NuGet packages contain this dependency information and handle the location and installation of any dependencies. Once the installation is done, a green check is shown next to the ELMAH package indicating that it has been installed. Sometimes after installing a package, a text file is displayed in Visual Studio with either additional directions or an indication of what was changed. Once the package is installed, you can use the library in your application immediately.

So what exactly happened when the package was installed? Figure G-10 shows that a reference to the ELMAH assembly was added to the project.

FIGURE G-10

image

Not only was the assembly referenced, but changes were made to the web.config file to support and configure ELMAH and the handlers and modules it provides. Figure G-11 shows a portion of the web.config file with some changes made by the NuGet package.

FIGURE G-11

image

The first package you install in a project creates a Packages folder. A subfolder is created in this folder for each package that is installed. In this particular example, the Visual Studio template for the project you created already installed some packages so the folder was already there. The folder will be located in the solution folder if there is one. If your project does not have a solution folder, the Packages folder will be created in the project folder. When you installed the ELMAH package, two subfolders were created. One was created for ELMAH and another was created for the package it depends on, the ELMAH core library. Figure G-12 shows the content of the packages folder showing the subfolders created by the ELMAH NuGet package.

FIGURE G-12

image

Each of these subfolders contains all of the files installed by the package, including the assemblies, the transform files defining the necessary configuration changes, the supporting documentation files, and the package file itself.

Uninstalling a NuGet Package

So what if you want to remove, or uninstall, a package? Removing a package is just as easy as installing it. Open the Manage NuGet Packages window again and select the Installed Packages tab. Figure G-13 shows the Manage NuGet Packages window with the installed ELMAH package selected.

FIGURE G-13

image

There is an Uninstall button on any package that has been installed. Note that the Uninstall button is shown only in the Installed Packages tab. If you have more than one project in your solution, you will have a Manage button instead of an Uninstall button. This scenario is covered in more detail later in this appendix. Click the Uninstall button. If the package depends on other packages, a window is displayed listing all of the packages that were installed along with the original package, asking if you want to uninstall them as well. Figure G-14 shows the window that is displayed when uninstalling the ELMAH package.

FIGURE G-14

image

Select Yes to uninstall the dependent packages. An uninstall progress window is displayed that’s similar to the install progress window shown in Figure G-9. Once the package or packages have been uninstalled, the reference to the assembly is removed, any changes to the web.config file are removed, and the subfolders in the Packages folder are removed.

Managing Packages at the Solution Level

The previous example installed the ELMAH package for the ASP.NET MVC project in your solution. However, what if you have more than one project in a solution? You can manage packages at a solution level as well. If you have been following along with this appendix, add another project to the solution you have been using. In this case, a class library project is a good choice. After adding another project to the solution, right-click on the solution. In the context menu, instead of an option for Manage NuGet Packages, you will see an option for Manage NuGet Packages for Solution. Figure G-15 shows the context menu containing the new menu option.

FIGURE G-15

image

Clicking on this new menu option will open the Manage NuGet Packages window as before. The difference you see is that when viewing the list of currently installed packages, upon selecting a package, the Install button is now a Manage button.

Clicking on the Manage button for any installed package displays the Select Projects window. Figure G-16 shows the Select Projects window.

FIGURE G-16

image

As you might have surmised, the Select Projects window allows you to choose which projects the package is installed for. This same window is used to remove a package from projects in the solution. If you wanted to install a new package, the process is the same as installing a package for a single project with the exception of this Select Projects window. When you install a package from the solution version of the Package Manager, you will be prompted to select which projects you want to install the package for.

Installing a package into multiple projects is one of the reasons the Packages folder shown in Figure G-12 is placed in the Solution folder. If you are installing the package into multiple projects in a solution, you don’t want to have multiple copies of the same files. Each project that will use the package simply references its files at the single solution-level location.

Managing NuGet Packages with the Console

If you prefer not to use the graphical interface, or if you are a developer who prefers to use the keyboard instead of the mouse, you can also work with NuGet packages using PowerShell commands. There is a console interface for working with NuGet. In order to open the console window, select Tools ⇒ Library Package Manager ⇒ Package Manager Console from the Visual Studio menu. This will open the Package Manager Console shown in Figure G-17.

FIGURE G-17

image

There are two drop-downs in the Package Manager Console. The first allows you to select the default package source that will be used by the commands you type in the console. The second allows you to select the default project the commands will act against. These defaults can be overridden using parameters of the PowerShell commands. The first thing you may want to do is view the packages that are available to install. The following command lists all of the available packages from the source selected in the package source drop-down:

Get-Package -ListAvailable

Because this command lists all of the available packages, it will scroll until all packages have been displayed. You can click the red stop symbol to stop the list of packages being displayed in the console. As of the writing of this appendix, there are over 11,000 unique packages in the default package source feed. Displaying the entire list is probably not very helpful. You can filter the results by using the Filter parameter. You can specify the same terms used in the search box from the previous example as the arguments to the Filter parameter. The following command shows how to search for the ELMAH package:

Get-Package -Filter Elmah -ListAvailable

Running this command will list all packages that contain the term “elmah” in the description or in the title of the package. Figure G-18 shows the results of running this command.

FIGURE G-18

image

If you want to know more about the Get-Package command, you can use the Get-Help command to list the parameters and get a description of the command. The following command displays help for the Get-Package command:

Get-Help Get-Package

Now that you can find the package that you want to install, you need to be able to install it. The command used to install a package is Install-Package. From the list of available packages shown in Figure G-18, you can see the package named elmah. To install the elmah package, you use this command:

Install-Package elmah

This will install the elmah package in the default project selected in the Default Project drop-down. As with installing a package using the Package Manager window, if the package you are installing has dependencies on other packages they will also be downloaded and installed. Figure G-19 shows the results of running the previous install command.

FIGURE G-19

image

Notice that the dependency on elmah.corelibrary was detected and that package was installed as well without you having to do anything special.

In order to view a list of packages that have already been installed, you can simply run the Get-Package command with no parameters. Figure G-20 shows the results of running this command.

FIGURE G-20

image

Once you have installed a package, there may be a need to update it to the latest version. You can view a list of updates available using the Updates parameter to the Get-Package command. The following command can be used to determine if there are any updates to the installed packages:

Get-Package -Updates

Figure G-21 shows the results of running this command to view any available updates.

FIGURE G-21

image

You can see in Figure G-21 that the jQuery package has an update available. In order to update a package, you use the Update-Package command. Like the install command, you simply pass the name of the package you want to update to the update command. In order to update the jQuery package, you run the following command:

Update-Package jQuery

Figure G-22 shows the results of running this update command.

FIGURE G-22

image

You can also remove a package using the console. To remove a package, you use the Uninstall-Package command. Like both the install and the update commands, the uninstall command simply takes the name of the package you want to remove as a parameter. For example, in order to remove the elmah package you installed earlier, you run the following command:

Uninstall-Package elmah

CREATING A NUGET PACKAGE

The first step in creating a NuGet package is to create one or more assemblies that you want to publish as a NuGet package. As an example, you can create a simple class library project that contains a single class. For the purpose of this example, Listing G-1 shows some sample code that can be used to create a simple class.

LISTING G-1: Sample class in a class library

    public class NugetMath
    {
        public int AddNumbers(int number1, int number2)
        {
            return number1 + number2;
        }
    }

Once you have one or more assemblies that you want to use to build a NuGet package, you need to download the NuGet.exe bootstrapper to create your packages. You can find the NuGet bootstrapper on the NuGet CodePlex site located at nuget.codeplex.com, from the Downloads page. Download NuGet.exe and put it somewhere accessible. To test that NuGet is accessible, open a command prompt and type nuget help to get help for the NuGet bootstrapper.


NOTE Note that you also need to tell NuGet that it can download any packages it needs to run. In order to do this, go into the Package Manager settings in the Visual Studio Options and check the option to Allow NuGet to Download Missing Packages During Build.

If you are going to publish your NuGet package to a NuGet repository that requires an API key, like the default NuGet repository, you need to get an API key that will identify the package as belonging to you. In order to get an API key for the default NuGet repository, go to www.nuget.org and register. Once you have registered, you will find your API key located on the My Account page. Figure G-23 shows the My Account page with the API key hidden.

FIGURE G-23

image

Once you have your own API key, you can run NuGet with the setApiKey parameter in order to have it remember your API key. That way, you don’t have to specify the key every time you create a NuGet package. The following command will cause NuGet to remember your API key, where your-key should be replaced with your actual API key:

nuget setApiKey your-key

There is more than one way to create a NuGet package. Which method you use depends on the complexity of your library. The first step to creating your NuGet package is to create the manifest file, which has a .nuspec file extension. A .nuspec file is an XML manifest that describes the NuGet package and any dependencies it has.

Creating a NuGet Package from an Assembly

You can create a .nuspec file from a single assembly. In order to create this file for a single assembly, you need to call the NuGet executable with the spec parameter and the path to the assembly. The command to generate a .nuspec file from your example assembly is as follows:

nuget spec NugetMath.dll

After running this command, a new file is created called NugetMath.dll.nuspec. Listing G-2 shows the content of the file that would be created by running this command.

LISTING G-2: Contents of the .nuspec file

<?xml version="1.0"?>
<package >
  <metadata>
    <id>NugetMath.dll</id>
    <version>1.0.0</version>
    <authors>Myname</authors>
    <owners>Myname</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package description</description>
    <releaseNotes>
        Summary of changes made in this release of the package.
    </releaseNotes>
    <copyright>Copyright 2013</copyright>
    <tags>Tag1 Tag2</tags>
    <dependencies>
      <dependency id="SampleDependency" version="1.0" />
    </dependencies>
  </metadata>
</package>

Some of the content in the file is default content. However, some of the content was pulled from the assembly metadata. The reason you reference the assembly when creating the .nuspec file is simply to use the metadata to automatically fill in some of the .nuspec file content. You can edit the contents of this file as necessary. You can view the full specifications for the .nuspec files on the NuGet.org site at http://docs.nuget.org/docs/reference/nuspec-reference.

For now, just remove the dependencies section since you don’t have any. Remove the lines that indicate they can be deleted, and edit any other fields as necessary. Listing G-3 shows the file contents after making the appropriate edits.

LISTING G-3: Contents of the .nuspec file after removing the dependencies section

<?xml version="1.0"?>
<package >
  <metadata>
    <id>NugetMath.dll</id>
    <version>1.0.0</version>
    <authors>Myname</authors>
    <owners>Myname</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>A sample library to do addition</description>
    <releaseNotes>This is the initial release.</releaseNotes>
    <copyright>Copyright 2013</copyright>
    <tags>Sample Math Addition</tags>
  </metadata>
</package>

Now that you have your manifest, there is one additional step you must complete before creating the NuGet package. The NuGet bootstrapper uses a particular convention for subfolders and files when creating packages. In order to have your NuGet package automatically create a reference to your assembly when the package is installed in a project, you need to place the assembly in a folder named lib. In the folder containing the .nuspec file, create a subfolder named lib and move the NuGetMath.dll into it. In order to create the package for this .nuspec file, you simply run the NuGet command with the pack parameter followed by the name of the .nuspec file. You can see an example of the command here:

nuget pack NugetMath.dll.nuspec

This command generates a file named NugetMath.dll.1.0.0.nupkg. This is your NuGet package file. A nupkg file is just a renamed .zip file. If you change the extension from .nupkg to .zip, you will be able to unzip the file to see its contents. You should see the .nuspec file in the root of the ZIP file along with some other supporting files and folders. You will also see the lib subfolder containing your assembly. The nupkg file can now be published to a NuGet repository to be included in the feed of available packages from that repository.

Creating a NuGet Package from a Project

Generating a .nuspec file from an assembly is the simplest way to create the necessary manifest. However, you may have need for a slightly more complex scenario. For example, if you have installed one or more NuGet packages in your library project, those packages then become dependencies for your NuGet package. Generating the .nuspec file from the assembly won’t pick up these dependencies. In this scenario, you can generate the .nuspec file from the .NET project. In order to demonstrate this, install a NuGet package into your class library project. Install Structuremap, which is an open source dependency injection/inversion of control library, into your project. If you have more than one project in your solution, make the project you want to install the package into the default project. You can search for Structuremap in the Package Manager window or issue the following command in the Package Manager Console:

Install-Package structuremap

Now that you have a NuGet package installed in your project, and thus have created a dependency on Structuremap, you can generate a .nuspec file from your project file. Doing so will take into account the dependency when you create the NuGet package. Open a console window and view the directory containing your .csproj or .vbproj file. From within that directory, issue the following command:

nuget spec

Issuing this command will generate a .nuspec file. If you look at the generated file, you will see some differences between it and the one generated directly from the assembly. Instead of reading metadata from the assembly to put into the .nuspec file, certain elements now contain tokens — such as $version$, $author$, and $description$ — that will be replaced when you create the package. The value of these tokens is pulled for the project metadata, but it is not pulled until you create the package because their values may change over time. A good example of this is $version$. You also may notice that the dependencies section is missing. Listing G-4 shows the generated .nuspec file.

LISTING G-4: Contents of the .nuspec file generated from the project

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>$description$</description>
    <releaseNotes>
        Summary of changes made in this release of the package.
    </releaseNotes>
    <copyright>Copyright 2013</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>
</package>

As with the previous example, after generating the .nuspec file, you can edit it as necessary. In this case you will remove the lines that indicate they can be deleted, replace the author token with a hardcoded value, and change any other values that are related to your package. The tags that are changed are bolded in Listing G-4. Listing G-5 shows the file after the edits.

LISTING G-5: Contents of the .nuspec file after editing

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>Myname</authors>
    <owners>Myname</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>$description$</description>
    <releaseNotes>Initial release.</releaseNotes>
    <copyright>Copyright 2013</copyright>
    <tags>Sample Math Addition</tags>
  </metadata>
</package>

Once the .nuspec file has been edited to your needs, you can create the NuGet package. To create the package from a project you will execute NuGet with the pack parameter and the name of the project file:

nuget pack NugetMath.csproj

Note that in the case of generating the NuGet package from a project, you specify the project file, not the .nuspec file when creating the package. The .nuspec file is still included in the package automatically. If you change the extension of the NuGet package to .zip, unzip the file, and view the NugetMath.nuspec file, you can see that all of the tokens have been replaced by values from the project metadata. Since there is a dependency on the Structuremap NuGet package, the dependencies section has also been added with an entry for the Structuremap dependency.

Publishing a NuGet Package

Now that you have created your NuGet package, you will want to publish it to a repository. You can publish your NuGet package directly on the www.nuget.org website. After logging on to the website and going to your account page, you can click on the Upload Package link and follow the directions online. Figure G-24 shows a portion of the Upload Your Package page.

FIGURE G-24

image

For those who would prefer to use the command line to publish their package, the process involves a single command. Once you have created your package as described, you will execute NuGet with the push parameter. The command to publish a NuGet package to the default Microsoft NuGet repository is shown:

nuget push NugetMath.1.0.0.0.nupkg

This command assumes you have previously stored your API key using the setApiKey parameter in a previous call to NuGet. You can override the API key and the package source location using command-line parameters.

HOSTING NUGET PACKAGES

NuGet packages would not be very helpful if you had no way to find them. A NuGet repository is often called a NuGet Gallery. The default NuGet Gallery is hosted by Microsoft. So far, this appendix has dealt with this default NuGet Gallery located at www.nuget.org. The packages located in the default NuGet Gallery are available to anyone searching the gallery. But what if you have a package that you want to be available only to you or to your organization or group? There are options for hosting your own NuGet Gallery.

File Share Hosting

The simplest option for hosting your own NuGet Gallery is to use a local folder or a file share. Although this option supports a read-only gallery that must be manually updated, it is a very quick way to set up a private gallery. To create a local gallery, create a folder on your local drive. Copy any NuGet packages (the *.nupkg files) you want to be available into the folder. That is it.

In the Visual Studio Package Manager options shown in Figure G-5, add a new package source. Specify the local gallery folder path as the source. Now when you view the available packages to install and specify the package source you just added, you will see all of the packages located in your gallery folder. This is a great option to allow you to test your own NuGet packages before publishing them to a public or private network gallery.

Creating a file share on a network drive works the same way. Access to a gallery on a network file share can be secured like any other file share. Whether you store your packages in a local folder or a network folder, you must update or add packages to the gallery manually. You have to copy any packages to the gallery folder manually. You also lose the ability to search packages using OData queries, which you can do when the gallery is hosted in IIS.

IIS Hosting

The next option for hosting a NuGet Gallery is to host it on IIS on an ASP.NET website. Luckily, and perhaps ironically, there is a NuGet package to help create your gallery. In order to create a NuGet Gallery hosted on IIS, begin by creating a new ASP.NET empty web application project in Visual Studio. Then you install the nuget.server NuGet package. If you are using the Package Manager window, search for the nuget.server package and install it. If you are using the Package Manager Console, use the following command to install the nuget.server package:

Install-Package nuget.server

The nuget.server package installs the files and creates the folders necessary to host your own NuGet Gallery. By default, packages are stored in the Packages folder. You can place any initial packages in that folder and mark them to be compiled as content so they are deployed with your website. You can change the folder used to store your packages by modifying the packagesPath key in the appSettings section of web.config. There are two additional appSettings that control whether the NuGet Gallery will allow packages to be published to it using the NuGet.exe bootstrapper. If the requireApiKey value is set to false, packages can be published to the gallery with no API key.

If the requireApiKey value is set to true, the determination of whether the gallery accepts packages to be published lies with the value of the apiKey. If the apiKey setting is deleted or its value is left blank, the gallery will be read-only and will not support publishing new packages using NuGet.exe. In order to support publishing packages, create a strong password and set the value of the apiKey to this value. This value is a shared public key that can be used by anyone publishing packages to the gallery.


NOTE Note that you should verify that there are not multiple compilation elements in the system.web section. Installing the nuget.server package on a website targeting .NET 4.5 can cause an additional compilation element specifying a target Framework of 4.0. If this is the case, simply remove the element instance targeting the 4.0 Framework.

Without making any changes to the default settings (except for the note), the gallery is ready to run. If you have been following along with this appendix, copy the NuGetMath package created earlier into the Packages folder and run the website. Figure G-25 shows the default page of the gallery.

FIGURE G-25

image

Notice the line in Figure G-25 that says “Click here to view your packages.” Clicking on the link displays the OData over ATOM feed of the packages in the gallery. Figure G-26 shows the page displayed when clicking on the link.

FIGURE G-26

image

If you want to test the gallery, you can add the address shown in Figure G-26 as a new package source in the Package Manager settings in Visual Studio. Publishing the website is no different than publishing any other website. After publishing, you have your own private NuGet Gallery.

EXTENDING VISUAL STUDIO WITH NUGET

The Package Manager Console is a PowerShell console within Visual Studio. So far, you have used the console to interact with NuGet. You can also use the console to interact with and automate Visual Studio. Using a NuGet package, you can add commands to the Package Manager Console that can perform standalone operations or interact with Visual Studio and your projects.

In the previous section on creating a NuGet package, you used the Nuget.exe bootstrapper to create your package. There is also a Windows GUI application for creating NuGet packages. The NuGet Package Explorer is a click-once application that makes creating packages very easy. It can also be used to view other NuGet packages to learn more about how they are structured. The NuGet Package Explorer is a CodePlex project and can be found at npe.codeplex.com. You can download and install the NuGet Package Explorer from there.

Creating the PowerShell Script Files

As an example of adding a command to the package manager, you will create a NuGet package that will add a command to generate a random password of variable length. Create a text file called init.ps1. The init.ps1 file runs the first time a package is installed in a solution. It only runs one time per solution. If the same package is installed in multiple projects in the solution, the script is not run during those installations. The script also runs every time the solution is opened. Listing G-6 shows the content of the init.ps1 file.

LISTING G-6: Contents of the init.ps1 file

param($installPath, $toolsPath, $package)
Import-Module (Join-Path $toolsPath GenRandomPassword.psm1)

The first line declares the set of parameters to the script. These parameters are passed into the script by NuGet. The second line of the script is used to import a PowerShell module. This listing specifies a script named GenRandomPassword.psm1.

Next you need to create this PowerShell module. Create a file called GenRandomPassword.psm1. Listing G-7 shows the contents of the GenRandomPassword.psm1 file.

LISTING G-7: Contents of GenRandomPassword.psm1 file

$rand = New-Object System.Random
 
function Get-RndPassword($num1) {
    1..$num1 | ForEach {
       $NewPassword = $NewPassword + [char]$rand.next(33,127)
    }
    return $NewPassword
}
 
Export-ModuleMember Get-RndPassword

The first line creates a System.Random object that is used in the Get-RndPassword function defined in the next line. The Get-RndPassword function accepts a single input parameter that is used as the upper limit of the range of numbers piped into the ForEach. The ForEach picks a random character code between 33 and 127 for each number in the range and adds that character to a variable $NewPassword. After the ForEach finishes executing, the resulting $NewPassword is returned from the function. The last line calls Export-Module on the function, which makes it available in the Package Manager Console.

Adding Files to the NuGet Package

With the two files you have created, you will create your NuGet package using the NuGet Package Explorer. Open the NuGet Package Explorer. Select Create a new package from the Common tasks dialog. Figure G-27 shows the NuGet Package Explorer after selecting the option to Create a new package.

FIGURE G-27

image

Drag both the init.ps1 and the GenRandomPassword.psm1 files and drop them onto the pane in the NuGet Package Explorer titled Package contents. For both files, the NuGet Package Explorer will recognize the files as PowerShell scripts and ask if you would like the files placed in the tools folder. Answer Yes for both files to have the Package Explorer create the tools folder and place both files in the tools folder. Now you need to edit the metadata for the package.

Editing the NuGet Package Metadata

You need to edit the metadata for your package to customize it for your particular package. Select Edit ⇒ Edit Metadata from the menu. The main field that should be edited is the Id field. The Id field should be set to the name of your NuGet Package. In this example, change the Id field to GenRandomPassword. Figure G-28 shows the NuGet Package Explorer after editing the metadata.

FIGURE G-28

image

Once you have finished editing the metadata, click the checkmark indicated in Figure G-28 in the upper left of the Package metadata pane.

Deploy the NuGet Package

Now you can publish the NuGet package. In order to publish your package to a hosted NuGet gallery, you can use the File ⇒ Publish menu item. But one of the best ways to test your package is to save it to a local or file share NuGet gallery. Choose File ⇒ Save from the NuGet Package Explorer menu and save the .nupkg file to the local folder or file share you used in the File Share Hosting section above.

Open the Package Manager Console and set the Package source to your local gallery. Type the following command to install the GenRandomPassword NuGet package:

Install-Package GenRandomPassword

Once you have installed the package, test the command you added to the console in your NuGet package. The following command will generate a random string of 12 characters.

Get-RndPassword 12

Figure G-29 shows the Package Manager Console after installing the NuGet package and executing the command added by the NuGet package.

FIGURE G-29

image

SUMMARY

In the past, it could be difficult to find, install, and configure libraries in your .NET projects. With NuGet, the complexity of adding libraries to your projects has been greatly diminished, if not eliminated altogether. Finding various libraries that provide the functionality you need is also much easier thanks to the centralized feeds provided with the NuGet repositories.

For developers creating libraries for others to use, creating NuGet packages has become an easy way to publish your libraries so that they can be discovered and installed more easily. Using NuGet to find and install libraries has become the de-facto standard by developers. For those development groups that want or need more control over access to libraries and group standardization, there are various hosting options for NuGet repositories. These options include creating private repositories accessible only to those developers within certain groups or companies.

NuGet can also be used to provide Visual Studio extensibility through the use of PowerShell commands. NuGet continues to grow and provide an easy outlet for open source developers to distribute their projects. Its integration with Visual Studio also facilitates extending projects with reusable functionality that saves both time and resources.