Nuget – How to!

There is this fascinating packaging and distributing technology called Nuget. You can basically distribute anything, through packages that can be downloaded directly to your development environment. When I say package, I mean library files, scripts, configurations, view files etc., put together in a distributable way.

At a glimpse: I created a new MVC web application and I want to reuse a certain third library available on the internet for datagrid, how do I do it? – Simple, find out a suitable package from nuget.org, download it using Visual Studio Package Manager, Your application will now have all files, scripts, and library(dlls) that’s required to use a datagrid (along with documentation, if available as a part of package).

Intro

As I said earlier, its a packaging and distribution mechanism. Below are certain points that will help you get started.

  • You are creating a web application and would like to distribute web controls you create for re-use
  • Normally, you would package all dll’s put the dependent files in folder and zip it to a location from where people could download your package and copy-paste re-use.
  • On the other hand, lets say you have a nuget driven approach, the entire process is simplified and streamlined.
  • For packaging your web control, you will build the solution using MSBuild scripts, generate output for deployment
  • Create a nuget manifest, which will have information about the component being distributed and its version information.
  • Once you have the manifest and the Build Output, run “Nuget.exe” to get the package created.
  • Host the package at any location, FTP or Web Server.

I am going to explain every step described above, as different topics below.

Why would you package?

Before that, Nuget – this is completely based on what your organisation needs, there are good and bad to it, based on what is required. For example, you don’t have to package an application if it’s not a re-distributable component, or if it cannot accept packages from nuget gallery, for whatever reason that may be. On the other hand, package anything that’s re-usable, Project Template, Custom Controls, Styles, Scripts and so on.

What to Package?

This is the most important question that you requires a lot of analysis. When I say analysis, below are certain stuffs that you need be prepared for, when you decide on what to package.

  1. Target Framework: This is the most crucial item, you need to know which .NET framework your component is targeted for. If your component is not targeted for any particular framework, well and good, your job is less complicated. If your component targets multiple framework, there has to be clear demarcation between different dependencies for each framework.

How To Package?

There are different ways to package using Nuget and they are

  1. Assembly package : A package can be created straight from an assembly based off its manifest.
  2. Project package : You can create a package from .csproj using “Nuget.exe” compiler
  3. Folder based package : Folder based conventional packaging is most flexible and allows multiple framework for packaging.

I’m not going through the details, as they are extensively available at Nuget.org Documentation.

What do I need to Setup Nuget?

Well, you dont need anything special. All you need to do is, go to Nuget.org/Documentation and download “Nuget.exe” – Thats it, you are all set to create your own package.
Now the question is how do we distribute this package. Well thats easier than creating a package. All you need to do is Sign-Up at Nuget.org and upload you package there, after which its available for anyone. That said, you cannot upload enterprise packages onto nuget gallery thats hosted for public. So, there are two different options

  • Host nuget at a FTP location and use the FTP path as feed location in Visual studio package manager
  • Host Nuget Gallery in local environment and provide the Website URL as feed location – Nuget gallery project is open source and anyone can download and host the project at enterprise level, if required with customization.

Host Nuget in local environment using “Nuget Gallery”

Difficulties I faced while hosting this project was with SQL Server configurations, you need to create a proper connection string and update the Web.config to point to an EMPTY DATABASE. When you run the application for the first time, the Nuget Manifest database will be created automatically. The site will also require you to create a FTP location to host nuget packages – basically they will be downloaded or uploaded via application to a FTP location.

  • NUSPEC – .nuspec file is the one which contains manifest details. While you are building the package using .csproj file, this .nuspec file has to be place at the same location as project file.
  • NUPKG – .nupkg is the output nuget package file, this file can be uploaded a nuget gallery hosted locally or onto server at Nuget.org.
Advertisements

MVC Web Profiling – Extension

Profiling is a simple concept that allows to track visitors on website and personalize the site based on the information available at your disposal. Profiling in .NET is so simple that, all you need to do is run a Command on Visual Studio Command Prompt and then write some 10 lines of configuration and code to enable profiling. Visual Studio SDK/.NET has the ability to create the database(tables) and all other infrastructure required for profiling. To get basic profiling enabled on your application all you would need is SQL Server

The default profile implementation is most intuitive and perfect way to handle profiling for your application. However, there may be scenarios where we will have to find alternates to implementation done in profiling. We can extend the ASP.NET profiling to use a custom provider, while we are allowed to reuse most of the core profile functionalities. Here I’ll walk you through basics of setting up an Profiling infrastructure and then details on customizing profile provider.

Steps to setup Basic Profiling

  1. To begin with, I assume that, you already have created a MVC3/MVC4 Web Project
  2. Add reference to System.Web.Profile. This is MS namespace for profiling.
  3. Create a strongly typed class – this class will have all properties that you wish to profile/save in profiling database
      • We will create a sample class and mark it as serializable.
      • This class will be serialized into an XML and stored in database.
        [Serializable]
        public class User
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Timezone { get; set; }
        }
    
  4. Implement an extension to get/set values from default profile provider
        public class UserProfile : ProfileBase
        {
            public User User
            {
                get { return (User)GetPropertyValue("User"); }
            }
    
            // Gets the profile of a specific user.
            public static UserProfile GetProfile(string userName)
            {
                return (UserProfile)Create(userName);
            }
    
            //Get Profile of current user
            public static UserProfile GetProfile()
            {
                return (UserProfile)HttpContext.Current.Profile;
            }
        }
  5. Create database – Execute following command and .NET automatically creates the database
    C:\Microsot Visual Studio 11.0>aspnet_regsql -A p -S SQLSERVER08 -E
    
  6. Add configurations to enable profiling
     <connectionStrings>
        <add name="sqldatabaseprovider" connectionString="Data Source=MACHINE\SQLSERVER08;Initial Catalog=aspnetdb;Integrated Security=True;" />
      </connectionStrings>
        <anonymousIdentification enabled="true" />
        <profile defaultProvider="ProfileProvider" inherits="ProfilingExtension.Profile.UserProfile">
          <providers>
            <add name="ProfileProvider"
            type="System.Web.Profile.SqlProfileProvider"
            applicationName="myApp"
            connectionStringName="sqldatabaseprovider"/>
          </providers>
        </profile>
     
  7. How to use profile in your code:
            [HttpPost]
            public ActionResult Index(string username)
            {
                //Create an instance of Profile Object
                UserProfile profile = new UserProfile();
    
                //Access custom property
                profile.User.FirstName = username;
                profile.User.Timezone = TimeZone.CurrentTimeZone.StandardName;
    
                //Save profile for current user
                profile.Save();
                return View();
            }
    

Things to Remember:

Profiling can be done for both authorized user and anonymous user. Basically, when profiling for an authorized user, profiling uses the current context to obtain the current user ID, which can be set using ASP.NET forms/Or any authentication mechanism. For anonymous users, profiling is not supported by default, it has to be explicitly enabled. When anonymous identification is enabled profiling creates a unique ID for a user and stores it in a cookie on user machine, which is periodically cleared. This unique ID is used by profiler to identify the anonymous user, every time he or she visits the website, and personalization can be done based on this.

Steps to Extend Profiler

  1. Create a database instance – good to have have most of the schemas as defined by default profile implementation
  2. Implement the Extension for ProfileProvider – MSDN article
  3. Implement the ProfileBase extension – Will provide access to custom profile properties along with default attributes.
  4. Modify the configuration – explicitly mention if the anonymous profiling is enabled and also configure the custom properties added – MSDN Article

We are done !!

Web Optimization

Microsoft.NET Web Optimization has a bundle of features which allows it to be the most easy to customize optimization framework available yet. When I say web optimization, I’m talking about bundling, compressing and caching the assets like JavaScript(s), style sheets(less/css). The basic implementation of optimization allows you to add a specific asset to bundle through code, every time asset list or the bundling order changes you have to modify the code to update the bundles on your page. To content manage bundling, we will take an XML based approach to this problem.

Primarily, there are 3 steps involved in web optimization,

  • Add Assets to Bundle
  • Process (compress/compile/order) assets using Parsers (Less compiler, JssMinifier, CssMinifer etc..)
  • Use Html helpers to print the cached asset path on the page

We will start by creating a Standard MVC Project. If you are using visual studio 2012, All the infrastructure required to start bundling is added by default in MVC project template. For other, using VS 2010 or earlier, you will need to Install .net framework 4.5. Most important aspect is that, System.Web.Optimization.dll is the assembly that is required to enable optimization for your project. Make sure that your are not using beta version of this assembly. Here, in this example we will taking a project template created out of VS 2010 and a machine having .Net framework 4.5 installed.

Download Source Code here

Activation of Optimization Framework

We will create an Http Module that will be invoked on PostMapRequestHandler. We are creating a module in this event because, optimization module requires Session and Current HttpContext to be populated, this is the application event that can have both. On Post Map Request State, we will initiate optimization framework by creating an Instance of our custom implementation, rather than calling the system libraries directly.

Custom Wrapper for Optimization

Our custom wrapper is the one which will actually enable us to use custom XML configuration to content manage the optimization framework. Features that we will try to enable are

  • Assets to add in JavaScript bundle – Folder based / File based.
  • Assets to add in Css/Less bundle – Folder based / FIle based.
  • Asset output path – Friendly links for assets.
  • Enable / disable optimization framework completely.

System.Web.Optimization: Supports custom pipelines

Custom compilers and processors, there are two Interfaces that can be extended for using custom processing.

IBundleTransform

Implement this interface to enable custom transformation for bundles. Let us say you want to compile a specific type of asset file not directly supported by optimization framework, you can use this interface to write your own custom transformer or plugin a third-party compiler that can compile the given asset. Let us consider that we want to compile Less files to generate css styles, to have Optimization do this we can use a third-party less compiler like dotLess.

IBundleOrder

Implement this interface to enable custom sorting of files while bundling. In general while bundling JavaScript files, you wight want to include the JQuery Framework files first and then include your library files after that in a given order so that none of the references are impacted. To enable this custom sorting you can extend this interface, In our example we will extend this interface to enable file based sorting of asset files. We will place a “bundle.txt” inside a folder and the IBundleOrder implementation will look for this file and order the assets based on the file order mentioned in the file.

MVC Helpers : Helpers to Use Bundles on a Page

We will take a master and child layout based approach to asset bundles. This will help us have multiple bundles added to framework and yet use only the required ones on a page, based on the layout used by current page. Apparently this will help us save on page load time. Normally adding all assets to framework and then using the current bundle list will output even the assets thats not required on a given page. The technical approach here will require us to add assets from sub-layouts to current http context and then output them on the master layout. This approach will help us have multiple sub-layouts, which controls assets required for a set of pages, and still have a master which can control the page layout.

Possible Enhancements

It is quite possible that you can inject compilers, orderers and minifiers at runtime, this wil further make the optimization framework generic and flexible to any kind of assets or change in any SEO approaches.