10/22 Update: This post was written before this feature became a part of NuGet.This feature is now a part of NuGet and the latest version of this information can be found on the NuGet docs site.There is also a sample project available.
Over the last few years the ASP.NET team has been including more and more libraries into the various project templates that we ship with Visual Studio and other products. The latest MVC 3 templates come with jQuery, jQuery UI, jQuery Validation, Modernizr, and Entity Framework. All this built-in functionality is great but one remaining snag is that upgrading all the packages by hand can be a pain. Of course the NuGet package manager is an excellent tool that solves the package upgrade problem but so far having project templates with preinstalled NuGet packages was not possible.
This post describes a new feature that will be shipping in NuGet 1.5: preinstalled NuGet packages. Since it is not documented anywhere at this time the purpose of this post is to describe how to create a VS project template with NuGet packages. If you play around with it please also provide feedback so we can make changes/improvements.
Authoring VS project templates is out of scope of this article but you can read more on how to create a project template directly using Visual Studio or using the Visual Studio SDK.
NuGet 1.5 is not out yet but the feature has already been checked in and you can try it out by grabbing a recent NuGet preview build and installing the Visual Studio add-in (note that you might have to remove the previous version via the Extension Manager first).
Preinstalled packages work using project template wizards. A special wizard gets invoked when the project gets instantiated. The wizard loads the list of packages that need to be installed and passes that information to the appropriate NuGet APIs. The project template needs to specify where to find the package nupkg files. Currently two package repositories are supported:
A frequent question is why not support downloading the nupkg files directly from http://nuget.org. We decided not to support such an option because users expect project templates to instantiate quickly and downloading files from the internet would slow things down. Also, it would not work on a plane or in other situations where a connection is not available.
To add preinstalled packages to your project template you need to:
<Assembly>NuGet.VisualStudio.Interop, Version=184.108.40.206, Culture=neutral, PublicKeyToken=null</Assembly>
<package id="jQuery" version="1.4.4" />
The remaining step is to specify the repository where NuGet can find the package files. As mentioned earlier, two package repository modes are supported:
The approach I recommend for deploying Visual Studio project templates is through a VSIX package (read more about VSIX deployment here). The VSIX method is preferable because it allows you to package multiple project templates together and allows developers to easily discover your templates using the VS Extension Manager or the Visual Studio Gallery. On top of that you can easily push updates to your users using the Extension Manager automatic update mechanism.
The repository attribute specifies the type of repository (“extension”) while repositoryId is the unique identifier of your VSIX (i.e. the value of the ID attribute in the extension’s vsixmanifest file).
You need to add your nupkg files as custom extension content and ensure that they are located under a folder called Packages within the VSIX package. You can place the nupkg files in the same VSIX as your project templates or you can have the packages be located in a separate VSIX if that makes more sense for your scenario (just note that you should not reference VSIXs you do not have control over since they could change in the future and your project templates would break).
If packaging multiple projects is not important to you (e.g. you’re only distributing a single project template), a simpler but also more limited approach is to include the nupgk files in the project template zip file itself.
However, if you are bundling a set of project templates that relate to each other and share NuGet packages (e.g. you are shipping a custom MVC project template with versions for Razor, Web Forms, C#, and VB.NET), we do not recommend adding the NuGet packages directly to each project template zip file. It needlessly increases the size of the project template bundle.
The repository attribute now has the value “template” and the repositoryId attribute is not longer required. The nupkg files need to be placed into the root directory of the project template.