Introduction
Nuget is a great plugin: it stays to .NET exactly as RubyGems stays to Ruby, providing thousand of packages for all tastes in one place.
There's nothing better than finding the library you need in one central repository and have it installed seamlessly into your project. Well, there is something better actually: publishing your library and making it available to all your fellow developers!
Background
We will create an awesome MVC HtmlHelper, see how to pack it for Nuget, and finally we will publish it so that anyone can use it. The article doesn't focus on the development of the helper but rotates around the steps required to create the Nuget package.
The editable MVC helper
Our helper is a wrapper around the CKEditor inline edit feature, providing persistence for the changed content. The default setup enables the WYSIWYG toolbar when ?editablemvc=true is appended to the querystring, saving via the content of the edited element to a file repository. Both the repository and the authorization can be changed within the EditableMvcBootstrap
class.
Here's an illustration showing the basics of the HtmlHelper, more info (Github and Nuget package links) can be found in the reference section at the end of the article:
The EditableMvcBoostrap class
Nuget permits changes on configuration files via transformation files and allows to add/remove source code files. This means that we can easily add a new class to our project but we will not be able to edit an existing one, like global.asax.cs. The WebActivator
package overcomes this limitation, allowing to easily hookup to the main application event on a separate file. In this case we want to add the setup of the helper and the registration of the js files, respectively on the beginning and the end of Application_Start
:
[assembly: WebActivatorEx.PreApplicationStartMethod(
typeof(EditableMvc.Web.EditableMvcBootstrap), "Start")]
[assembly: WebActivatorEx.PostApplicationStartMethod(
typeof(EditableMvc.Web.EditableMvcBootstrap), "PostStart")]
namespace EditableMvc.Web
{
public static class EditableMvcBootstrap
{
public static void Start()
{
EditableMvcConfig.RegisterRepository = () =>
new SimpleFileRepository("~/App_Data");
EditableMvcConfig.RegisterAuthorization = () =>
{
var editable = !string.IsNullOrEmpty(
HttpContext.Current.Request.QueryString["editablemvc"]);
if (editable)
{
return Convert.ToBoolean(
HttpContext.Current.Request.QueryString["editablemvc"]);
}
return false;
};
}
public static void PostStart()
{
BundleTable.Bundles.Add(new ScriptBundle("~/bundles/editableMvc").Include(
"~/Scripts/jquery-ui-{version}.js",
"~/Scripts/ckeditor/ckeditor.js",
"~/Scripts/ckeditor/plugins/editablemvcsave/editablemvcsave.js",
"~/Scripts/editablemvc.js"));
}
}
}
Create the package
Create an empty class library and name it with the desired Nuget name. Let's keep in mind that if there's any compiled file, the DLL of the project needs to be included in the package. We don't want to compile the default files coming with an MVC project (like routing, controllers etc.), so the choice of using an empty class library as the target for the nuget package. The required files will be copied from the MVC project (containing the working helper) to the class library.
Copying the files
Let's add to the class library the files we want to deploy on the user project. Note that the bootstrap class is in the App_Start folder: Nuget will create the folder on the target project if this doesn't exist, or it will just add the file to the existing folder if this is found.
Transform files
While we are not allowed to override or delete existing files, we can transform the ones we are deploying: change the file extension of the source file from .cs to .cs.pp and start using any project property to change the output of the file. The namespace can then by changed with:
namespace $rootnamespace$.Controllers {}
Create the package using Nuget Package Explorer
While it is possible to use the Package Manager Console to create a package, having a GUI can help, so let's download the Nuget Package Explorer.
Similar to the creation of an MSI package, the tool allows to drag into the content folder the deployable resources and in the lib folder the required dependencies (like the project DLL, if required).
Other dependencies, like external packages or .NET assemblies, can be added by editing the package metadata:
<dependencies>
<group targetFramework=".NETFramework4.5">
<dependency id="WebActivatorEx" version="2.0.1" />
</group>
</dependencies>
<frameworkAssemblies>
<frameworkAssembly
assemblyName="System.Runtime.Serialization"
targetFramework="" />
</frameworkAssemblies>
Package metadata
The information about your package is contained in a manifest file *.nuspec and is used through the publishing process to identify (along with info like library name, author, etc.) the version of the package. You are not allowed to override an existing version of a library, this is to avoid breaking code using that version, but only to publish a new version of the assembly.
Publish the package
Register on the Nuget website and retrieve your API key. Use it to publish the package from the package explorer. Finally check on the Nuget site the package is listed under your Packages list.
Points of interest
Publishing a Nuget package is a simple process mainly because of the few rules the package manager forces us to follow: we are only allowed to add files to an existing project or modify its configuration file. We saw how to easily hook into the main events of the host application without having to alter existing files, and we ended by creating and publishing a package using the Nuget Package Explorer tool.
References
The source code of the article can be found here, while the Nuget package of the helper can be downloaded here.
A video of the helper in action can be found here.