Compact CSS And Javascript With MVC And SquishIt

SquishIt

SquishIt is a library for ASP .Net implemented by Justin Etheredge of CodeThinked that will take several separate javascript or CSS files and produce a single compacted file as ouput which is then returned to the client, rather than the several individual source files.

This is great as it saves bandwidth by both reducing the number of requests that need to be made, as well as compacting the files by removing excess white space and comments.

Less

One of the additional benefits of using SquishIt is built in support for dotLess. dotLess is a .Net port of the CSS extension Less, which was originally implemented for Ruby. This adds a number of neat features such as variables and mixins, which makes it easier to create well structured and maintainable CSS.

@brand_color: #4D926F;

#header {
  h2 {
    color: @brand_color;
  }
}

Compacted

To make use of Squishit, all we need to do is change how we reference our CSS and javascript files. Instead of including tags in our <head> element, we make a call to Bundle.Css() or Bundle.Javascript() instead:

  @MvcHtmlString.Create(Bundle.Css()
    .Add("~/Content/style.less")
    .Add("~/Content/jq.datatable.css")
    .Add("~/Content/jquery-ui-1.8.14.custom.css")
    .Add("~/Content/colorbox.css")
    .Render("~/Content/Site.min.css"))

  @MvcHtmlString.Create(Bundle.JavaScript()
    .Add("~/scripts/jquery-1.6.2.min.js")
    .Add("~/scripts/jquery.dataTables.min.js")
    .Add("~/scripts/jquery-ui-1.8.14.custom.min.js")
    .Add("~/scripts/jquery.colorbox-min.js")
    .Render("~/Content/Site.min.js"))

In release mode this will combine the separate files into a single file with the specified name, as well as performing minification.

When running with debug on in your web.config (<compilation debug=”true”>), the files are not combined by default. You can alter this behaviour by chaining a call to ForceRelease() before the call to Render(). Likewise, a call to ForceDebug() can be made to keep everything seperate when doing a release build with debug off.

Using Multiple Layouts

It’s not uncommon to have multiple layouts when developing a production web site with MVC3. There is a consideration to be made here, as if you wish to include different CSS / Javascript depending on the current layout, if you use the same output filenames for each layout, it could cause SquishIt to re-minify the files if going from a layout that uses one set of files, to one that uses a different set.

There are two ways round this:
1) Include all CSS and all Javascript for the entire site when bundling. You could extract this to a partial view that is included by each layout so that it only needs updating in one place.
2) Change the name of the output files depending on the view. This will ensure that re-minification only occurs when there are actual changes to the source files.

Permissions

One thing to note is that when using a release build, SquishIt may require write access to the directory containing the target files, which in our case is ~/Content. This is because should any of the source files be updated, SquishIt will want to output a new ‘squished’ version.

Summary

SquishIt takes all of your javascript, all or your CSS and squishes them into the smallest size it can. This is great in a world of heavily interactive web sites where the weight of scripts and CSS can add significant time to the loading of a page.

Razor And HtmlHelper Extensions

HTML helpers can be fantastically useful when working on an ASP .Net MVC project, and they’re dead simple. They boil down to methods which are used to encapsulate functionality to help reduce the amount of logic we end up with in a view.

For example there are helpers available to create labels and form fields, taking a property as input, and generating the relevant HTML for it.

Writing your own HTML helpers is easy and achieved by writing an extension method for the HtmlHelper class. I often hit a stumbling block when writing an extension which manifests itself in the following way:

Compiler Error Message: CS1061: ‘System.Web.Mvc.HtmlHelper’ does not contain a definition for ‘TestMethod’ and no extension method ‘TestMethod’ accepting a first argument of type ‘String’ could be found (are you missing a using directive or an assembly reference?)

An Example Extension Method

To demonstrate how to fix this, we need a quick example of an HTML helper extension method:

namespace MVC3Test.Helpers
{
  public static class HtmlExtensions
  {
    public static MvcHtmlString TestMethod(this HtmlHelper htmlHelper, string input)
    {
      return MvcHtmlString.Create(input.Trim());
    }
  }
}

Make it work

The problem is caused by the fact that we don’t have a reference to the namespace where the extension method lives. We have two options for fixing this:

Add a using directive to the view

The first thing we could do is just add a @using directive to the top of the view specifying our helper namespace:

@using MVC3Test.Helpers

Update View Folder Web.config

Adding using directives to each view that uses our helpers will quickly become tiresome. An easier way to apply this throughout the project is to update the web.config to reference the namespace.

This can happen at either the view folder level, or application folder. Either way, you need to update the web.config to add a new namespace entry, which should look something like this:

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        ...
        <add namespace="MVC3Test.Helpers"/>
        ...
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Summary

Html Helpers are a great way to reduce the complexity of your views and reuse code that is often repeated.

Just remember that when writing your own, it must be referenced from either the view, or web.config!

Ninject, MVC3 And Web Requests

Continuing to play with Ninject and MVC3, I wanted to explore further how Ninject can help manage objects over the life of a web request. One of the great things about Ninject is that it allows you to easily change the scope in which objects live through use of Activation Behaviours.

Behave Yourself!

Using Ninject, you can control when new instances of objects are created with Activation Behaviours (although this documentation appears to be out of date at the time of writing).

To set the activation behaviour of a binding, you append a call like so:

Bind<ITestInterface>().To<TestClass>().InTransientScope();

Ninject has the following scopes built in:

  • TransientScope: A new instance is created for each request.
  • SingletonScope: Only a single instance of an object is created, and the same instance is returned every time.
  • ThreadScope: A new instance is created for each thread.
  • RequestScope: A new instance is created for each web request.

RequestScope and MVC

What I was interested in was whether the RequestScope would create a new instance of something at the start of a web request, and then immediately clean said object up at the end of the request, so that objects wouldn’t be kept around longer than they were needed.

A simple test ensued:

  public class MvcApplication : NinjectHttpApplication
  {
    private static ILog logger = log4net.LogManager.GetLogger("default");

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

      routes.MapRoute(
          "Default", // Route name
          "{controller}/{action}/{id}", // URL with parameters
          new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
      );

    }

    protected override Ninject.IKernel CreateKernel()
    {
      return new StandardKernel(new MyModule());
    }

    protected override void OnApplicationStarted()
    {
      base.OnApplicationStarted();

      AreaRegistration.RegisterAllAreas();
      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
    }
  }

  public class MyModule : Ninject.Modules.NinjectModule
  {
    public override void Load()
    {
      Bind<ITestInterface>().To<TestClass>().InRequestScope();
    }
  }

  public interface ITestInterface { }

  public class TestClass : ITestInterface, IDisposable
  {
    public void Dispose()
    {
      System.Console.WriteLine("Disposing");
    }
  }
  public class HomeController : Controller
  {
    ITestInterface test;
    public HomeController(ITestInterface test)
    {
      this.test = test;
    }

    public ActionResult Index()
    {
      return View();
    }
  }

All I did here was setup a controller that would take an instance of a disposable test class. We know it gets created and passed to the controller, so all I wanted to see was that it was disposed at the end of the request. I did this by setting a breakpoint in the dispose method of the class and debugging through Visual Studio.

If you run up the project, you’ll see that the breakpoint gets hit after the request has been served, nice and promptly; exactly what I was hoping for.

Making NHibernate Behave

The recommended way or using NHibernate with MVC is to have a single session created per request. That is each time a client makes a request for a page, a new session is opened and kept open until the request is complete and data is returned to the client.

Sounds a little like the RequestBehaviour activation type fits perfectly here doesn’t it?

To test this, we need to setup NHibernate and create a simple user class and repository. So to start, here’s how I like to get my session factory:

namespace DITest
{
  public static class SessionFactoryProvider
  {
    private static ISessionFactory sessionFactory;
    private static Object lockObj = new Object();

    private static void BuildSessionFactory()
    {
      string connStr = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

      sessionFactory = Fluently.Configure().
        Database(MsSqlConfiguration.MsSql2005.ConnectionString(connStr)).
        ExposeConfiguration(c => c.Properties.Add("hbm2ddl.keywords", "none")).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MvcApplication>()).
        BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
      if (sessionFactory == null)
        lock(lockObj)
          if (sessionFactory == null)
            BuildSessionFactory();

      return sessionFactory.OpenSession();
    }
  }
}

And this is registered with Ninject like so:

Bind<ISession>().ToMethod(x => SessionFactoryProvider.OpenSession()).InRequestScope();

Next, a simple user class, mapping (I’m using FluentNhibernate here to do the mapping) and repository (all in one place for brevity):

namespace DITest
{
  public class User
  {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
  }

  public class UserMap : ClassMap<User>
  {
    public UserMap()
    {
      Id(c => c.Id);
      Map(c => c.Name);
      Map(c => c.Age);
    }
  }

  public class UserRepository
  {
    ISession session;
    private IQueryable<User> Users
    {
      get { return session.Query<User>(); }
    }

    public UserRepository(ISession session)
    {
      this.session = session;
    }

    public IList<User> GetUsers()
    {
      using (session.BeginTransaction())
      {
        var query = from c in Users select c;
        return query.ToList();
      }
    }
  }
}

Finally, updated the controller to pull some information from the database:

  public class HomeController : Controller
  {
    UserRepository repo;
    public HomeController(UserRepository userRepo)
    {
      repo = userRepo;
    }

    public ActionResult Index()
    {
      ViewBag.Users = repo.GetUsers();
      return View();
    }
  }

To verify this was all working correctly and the session is being closed properly, I setup logging to log debug information, which churns out tons of useful information:

<logger name="NHibernate" additivity="false">
  <level value="DEBUG"/>
  <appender-ref ref="rollingFile" />
</logger>

<logger name="NHibernate.SQL" additivity="false">
  <level value="DEBUG"/>
  <appender-ref ref="rollingFile" />
</logger>

Then after running up the page and doing a request, we can look at the generated log and see what’s been happening:

14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] opened session at timestamp: 634462405708, for session factory: [/b9e13234ae244e18b7f2ce1923c58e48]
14/07/11 12:42:50 DEBUG Begin (Unspecified)
14/07/11 12:42:50 DEBUG Obtaining IDbConnection from Driver
...//edited for brevity
14/07/11 12:42:50 DEBUG IDbTransaction disposed.
14/07/11 12:42:50 DEBUG transaction completion
14/07/11 12:42:50 DEBUG aggressively releasing database connection
14/07/11 12:42:50 DEBUG Closing connection
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] running ISession.Dispose()
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] executing real Dispose(True)
14/07/11 12:42:50 DEBUG closing session
14/07/11 12:42:50 DEBUG running BatcherImpl.Dispose(true)

I’ve cut out a lot of the logging that just details queries are happening so that we can see what we care about; that the session is being closed properly after the requests have happened, and not before!

Summary

We looked at the various types of activation behaviour that Ninject supports, delved deeper into RequestBehaviour and verified that it is in fact doing what it says on the tin, and then saw how this is useful when working with MVC and NHibernate.

So now we have an NHibernate session that will last for the duration of a request. What would be really useful now is some concept of a unit of work, to allow multiple Nhibernate requests to be batched into a single transaction. Stay tuned!

Ninject And ASP .Net MVC3

I’ve mentioned Ninject before, it’s an excellent dependancy injection framework that lets you keep your code loosely coupled.

I’ve also mentioned that I’ve been working with the MVC Framework quite a lot of late, and what’s neat is that hooks are provided that make it easy to use your own dependancy injection framework. To that end, this post will be looking at how Ninject can be integrated with MVC3, and why that’s awesome!

I’ll be working with a clean MVC3 project created in Visual Studio 2010. There are a couple of ways of integrating Ninject; using the IDependancyResolver interface, or inheriting from NinjectHttpApplication.

Option 1: IDependancyResolver

All we need to do here is implement IDependancyResolver and then register an instance of it on application startup.

So a simple implementation for Ninject will look something like this:

using System;
using System.Web.Mvc;
using System.Collections.Generic;
using Ninject;
using Ninject.Modules;

public class NinjectResolver : IDependencyResolver
{
  IKernel kernel;

  public NinjectResolver(INinjectModule[] modules)
  {
    kernel = new StandardKernel(modules);
  }

  public object GetService(Type serviceType)
  {
    return kernel.Get(serviceType);
  }

  public IEnumerable<object> GetServices(Type serviceType)
  {
    return kernel.GetAll(serviceType);
  }
}

And we register this in Application_Start with a simple call like so:

var resolver = new NinjectResolver(new MyModule());
DependencyResolver.SetResolver(resolver);

MVC3 will then use this object when trying to instantiate an instance of a class, but will fall back to it’s built in methods for locating objects if this fails. What this means in practice is that you don’t need to worry about registering all of the default objects MVC3 uses such as the controller factory, leaving you free to just deal with the stuff you care about.

Option 2: NinjectHttpApplication

The second option is to make use of Ninject’s MVC3 extension which can be found here.

In this case, all we need to do is change our MvcApplication class (found in Global.asax) to inherit from NinjectHttpApplication instead of MvcApplication, and then implement CreateKernel to register the modules we’ve created.

public class MvcApplication : NinjectHttpApplication
  {
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

      routes.MapRoute(
          "Default", // Route name
          "{controller}/{action}/{id}", // URL with parameters
          new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
      );

    }

    protected override void OnApplicationStarted()
    {
      base.OnApplicationStarted();
      AreaRegistration.RegisterAllAreas();
      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
    }

    public override IKernel CreateKernel()
    {
      return new StandardKernel(new MyModule());
    }
  }

And that’s it; now Ninject will be used to resolve any dependencies that are requested when the object model is being built.

Which Approach?

But which of the two approaches should you use? It doesn’t matter hugely, the first option allows for a very quick integration, you could even register a dependency resolver in a much more concise fashion making use of lambdas like so:

var kernel = new StandardKernel(modules);
DependencyResolver.SetResolver(
    t => {
        try { return kernel.Get(t); }
        catch { return null; }
    },
    t => kernel.GetAll(t)
);

However, using Ninject’s MVC3 extension is marginally more self contained, so I tend to prefer making use of NinjectHttpApplication instead. Note that Ninject will still find the right controllers without registering them, so there is no need to register all your controllers unless you want to add additional configuration to them.

If you think you’re likely to want to change your DI framework, then it would make more sense to make use of the IDependancyResolver interface so that you can drop in a quick replacement, although personally I think that scenario is somewhat unlikely.

Now you’re loosely coupled

So that’s a couple of simple ways to integrate Ninject with MVC3; not too hard to achieve and provides a lot of power and flexibility.

Writing A Simple Jquery Plugin

Jquery is a fantastic Javascript library that makes manipulating the DOM a breeze. Its usefulness lies in the powerful selectors which make it easy to pick which part of the DOM you want to work with, and many functions with which to manipulate the selected objects.

Jquery provides a lot of functionality, but like any good library, also provides the ability to easily extend its capabilities. I recently found it useful to do this, so here’s a quick run down on how to do just that.

The Barebones

To start with we’ll just put together a bare plugin so that we can see the structure:

(function($) {
  $.fn.mask = function() {
  //body goes here
  };
})(jQuery);

This adds a new function, mask, to the jquery object. You could use it like so:

  $('#objectToMask').mask();

An Overlay

The reason I started to look into this was that I wanted to encapsulate a piece of functionality that would allow an overlay mask to be applied to an arbitrary element. This is useful when loading something asynchronously to let the user have some visual feedback.

Firstly the mask function:

(function($) {
  $.fn.mask = function() {
    if ($("#overlay").length == 0) {
      var $overlay = $('<div id="overlay"><img src="images/loader.gif" id="img-load" /></div>');
      $("body").append($overlay);
    }

    $("#overlay").css({
      opacity: 0.5,
      top: this.offset().top,
      left: this.offset().left,
      width: this.outerWidth(),
      height: this.outerHeight()
    });

    $("#img-load").css({
      top: (this.height() / 2),
      left: (this.width() / 2)
    });

    $("#overlay").fadeIn();
  };
})(jQuery);

This is pretty straight forward; We create the overlay element if it doesn’t exist, set its position along with the loading image position, and then fade it in.

The unmask function, is shorter, as it just needs to hide the element:

(function($) {
  $.fn.unmask = function() {
    $("#overlay").fadeOut();
  };
})(jQuery);

Summary

And that’s all there is to it. Extending Jquery is a relatively simple and straightforward process that’s well worth investigating when you want to encapsulate a piece of functionality to make it easily reusable.

ASP .Net Sessions And The Idle Worker Timeout

I’ve been dealing with the realm of an ASP .Net application recently, and one of the requirements was that the session state should last for up to 60 minutes, which sounded straight forward enough, just whack the following in web.config:

<system.web>
    <sessionState timeout="60"/>
</system.web>

Which works fine in theory, however after leaving the site idle for 20 minutes, the session state suddenly goes away.

After much hair pulling, I finally stumbled accross the Idle Process setting in IIS under the Application Pool configured for the website.

By default this is set to 20 minutes, and as the default Session State is in-process, it gets wiped when the worker process is recycled. On a deployed website this probably wouldn’t be an issue as regular requests will keep the process alive, however in a single user testing environment this can obviously cause a problem when trying to test a session timeout greater than 20 minutes.

So there are two solutions to this:
1) Increase the Idle Process timeout setting
2) Use an out of process Session State (StateServer or SQLServer)

The second option simply requires that anything stored in the state be serialisable, and that you enable the ASP .Net StateServer process, although there is a slight cost as the objects have to be serialised and deserialised for each request.

For now I’ve simply increased the Idle Process timeout setting, however it’s definately worth looking at using an out of process Session State as the Worker Process will still be restarted occasionally (Although also configurable) to ensure the health of the web server.

Not sure I totally agree with the approach of reliability through restarts, but I guess it’s at least somewhat foolproof.