Saturday, June 27, 2009

JavaScript Design Tips

As the use of JavaScript continues to grow in its involvement with developing cutting edge web applications, so too will grow the amount of JavaScript developers will be asked to write.  In the pasts few years many JavaScript framework have emerged to help ease the burden of writing large amounts of JavaScript by encapsulating common operations and providing abstraction against the variety of JavaScript Engine implementations among the popular browsers.  However, even with these frameworks in place JavaScript can still a pain in the butt to code and maintain.  Below I will talk about some tips that can be used to improve the code your write as well as increase the productivity of writing the code.

At the end of this article I have posted the code for a very simple ASP .NET application that employ's these strategies in its design.

Unobtrusive JavaScript
We often talk about the graceful degradation with respect to developing computer applications. How to handle a condition where the program cannot achieve a desired result become circumstances disallow it; the same is true when developing a JavaScript driven application.  In its purest form developing an Unobtrusive JavaScript application involves an application that functions with or without JavaScript. The principle idea is that JavaScript should NOT drive a page but rather should AUGMENT it.

While this idea is very good in practice, it is often never done to the purest form due to budget or time considerations.  However, the central point of Unobtrusive JavaScript is the user should be alerted that this application can work better with JavaScript. The user should not click on features with the expectation that they are available and have the feature be "dead" due to lack of JavaScript.

The main practice with Unobtrusive JavaScript is to separate all JavaScript code out from the presentation, that is the HTML.  This means no defining of event handlers in the tag's themselves, but rather using an external JavaScript file to augment the page.  This has many advantages, for one it allows you to more easily take advantage of certain syntaxes such as closure available to you from JavaScript. In addition, it also allows the browser to cache the JS file, therefore lightening the load when the document is being downloaded.  This is the same practice we employ with CSS.

You can almost consider there to be a fourth layer to the application design: Models, Controllers, View, and Interaction.  The additional layer interaction, is the layer that allows the view to manipulate it self as well as talk to the controllers; basically provide interactivity to the view.

Closure
Closure is a syntax advantage that can be leveraged to help obfuscate your code and provide decreased visibility to sensitive values. It can also help to circumvent undesirable parsing of values in certain situations. When developing JavaScript intensive application you always need to consider malformed data as a potential security risk. Remember that using a tool such as Firebug users can have free reign with your pages and even wire up their own JavaScript events to call your services.  The code is all right there in front of them and the security of these services is something you must be constantly aware of.

By using closure you can effectively store your values in the JavaScript runtime, I have an example of this in my sample application available for download.  But JQuery takes this a step further by providing the JQuery data cache which allows you to store data on a per node basis using a hashtable; consider the following code:

var totalAge = 15;
$("#totalAge").text(totalAge).data("total", totalAge);

Again we can put whatever data we want in the data cache and identify it with a key.  As you probably have guessed this is not as secure as the closure idea since our user could easily wire up a JavaScript event to alert back the values used here. What  I tend to use this for is to store data that I can use in client side operations so that I dont have to parse numbers, but rather can read the value in native JavaScript format.

Prototype & JQuery Plugin Architecture
If you have ever written a .NET extension method then you already understand the basics of JavaScript prototyping.  JavaScript contains several standard types: Number, Date, String, Integer, Array, Boolean, as well as others.  All of these types contain a property named prototype that can be used to add custom methods onto the type.  However, much like the namespace containing the extension method must be available in .NET, you must have the prototyped method definition in scope on the page the use it.  You define a prototype method like this:

   1:  String.prototype.parseToNumber = function() {
   2:      // convert to a number
   3:      var number = parseInt(this);
   4:      if (!isNaN(number)) {
   5:          return number;
   6:      }
   7:   
   8:      return 0; 
   9:  }

Here we are creating a new function for a String that will attempt to parse the string value to a Number, notice that we return zero if we are unable to do this.  So we can see its usage here:

var totalAge = $("#listing :text").SumContainer(function($obj) {
        return $obj.val().parseToNumber();
 });

By using prototype functions we can promote cleaner more reliable code the emphasis reuse and centralizes functionality to make maintenance easier.  Also included in this sample is a custom JQuery plugin I wrote called SumContainer.  Remember that JQuery is essentially a query language built on top of JQuery. We make queries into the DOM and get results, we then call functions to act on the results.  Here is the code for the SumContainer plugin:

   1:  jQuery.fn.SumContainer = function(fn) {
   2:      var total = 0;
   3:      this.each(function() {
   4:          value = fn(jQuery(this));
   5:          total += value;
   6:      });
   7:   
   8:      return total;
   9:  };

What this does is, by using fn we effectively prototype JQuery with a new function called SumContainer, which takes as a parameter a function that denotes HOW to get the value to sum.  As you will notice above when we call SumContainer we pass it an anonymous function that is passed a JQuery reference to the current element within the plugin.

While this technique is, to my knowledge, contained to just the JQuery world, you can understand that both of these techniques are doing roughly the same thing: centralizing code and make it easier to create libraries and frameworks to support your code; in fact the vast majority of frameworks and libraries and built on these two concepts.

To further demonstrate these techniques and tips I invite you to download my code and the slides from this presentation.  I have done the best I can commenting the source code to help you understand what is going, but please feel free to leave a comment with questions.

Tuesday, June 23, 2009

Silverlight 2 Page Switching

Silverlight 2 represents a giant leap forward for developers of Rich Internet Applications (RIAs); the ability for .NET developers to leverage their programming skills in the wide variety of languages supported by the .NET framework permits for a wide degree of flexibility in application development. However, as with all new techniques there are shortcomings and areas that need extra work from developers.  One area within Silverlight 2 that falls into this category is page switching.

Jesse Liberty has a great two part tutorial on switching pages effectively in Silverlight: Part 1, Part 2.  However, this method has a rather serious design flaw: it fails to reuse the interface when switching.  This means that if I have two pages with the same interface, I am essentially recreating the interface for each page.  While I can certainly encapsulate static portions in user controls, the fact remains that I am still reloading these each time.

Building on Jesse's tutorial I took things one step further and allowed the user to Switch pages in content area similar to how things are handled with ASP .NET Master Pages.  This technique combines the effectiveness of Jesse's switching method with a more modular design.  This technique, however, pales in comparison to the flexibility offered in the Silverlight 3 Navigation Framework, which should be used exclusively once available.

To begin you will at least four pages, as shown below:2009-06-23_1130

In this case we are using Page.xaml as the main page that will  host the others, thus we define a new instance of Page.xaml as the RootVisual in App.xaml.cs.  The Page.xaml XAML markup looks like this:

2009-06-23_1133

Notice the two areas I have marked:

  1: xmlns:local="clr-namespace:TransitionApplication"
  2: 
  3: <local:Switcher x:Name="Switcher" Height="110" Width="300"
  4:                 HorizontalAlignment="Center" VerticalAlignment="Center" />

In this code we are simply creating a reference back to our application and including a user control called Switcher into the application markup.  The code for switcher is rather unique as it does not contain any markup, this is intentional.  Basically we will use Switcher to load other pages into the given content area. The code-behind for Switcher looks like such:

   1:  public partial class Switcher : UserControl
   2:  {
   3:       public Switcher()
   4:       {
   5:           InitializeComponent();
   6:   
   7:           if (Content == null)
   8:           {
   9:                Content = new Page1();
  10:           }
  11:       }
  12:       
  13:       public void Navigate(UserControl ucControl)
  14:       {
  15:            Content = ucControl;
  16:       }
  17:  }

The purpose of this code is to provide a means for the parent page to navigate to new pages via the Navigate method.  By default we will load Page1 into the application when it is first started.

From this point, our event handlers in the main page will suffice to perform the switch, an example is provided below, this is from Page.xaml.cs:

   1:  public partial class Page : UserControl
   2:  {
   3:       public Page()
   4:       {
   5:            InitializeComponent();
   6:       }
   7:   
   8:       private void Button1_Click(object sender, RoutedEventArgs e)
   9:       {
  10:            Switcher.Navigate(new Page1());
  11:       }
  12:   
  13:       private void Button2_Click(object sender, RoutedEventArgs e)
  14:       {
  15:            Switcher.Navigate(new Page2());
  16:       }
  17:  }

This is pretty simple, each button set the Content of the Switcher to the respective page.  Of course this is a simple example, but you can get an idea of how this could could work in a larger application.

Monday, June 15, 2009

The Silverlight Toolkit

Recently I have decided to educate myself on Silverlight 2.  I did some playing during Silverlight 1, but was not all that impressed so I really put it aside.  However, I have always believed that learning a Rich Internet Application (RIA) platform like Silverlight or Flex is very important moving forward because it shores up many of the shortcomings of traditional RIA development using JavaScript, even when using frameworks like JQuery, Prototype, and others.  True RIAs are best when created using the sandbox approach of a plugin driven experience.  To that end I think Silverlight will someday surpass Flex/Flash because of the better developer experience using .NET over ActionScript, as well as other facts.

As part of my research into Silverlight I looked at what pre-existing controls sets are available for use; to that end I came across and have been experimenting with the Silverlight Toolkit.  Much like the Ajax Control Toolkit, the Silverlight Toolkit contains made to measure controls and themes that can instantly be used in your Silverlight applications to improve both the look of the application as well as the user experience.  Be careful when downloading this though, it caused me some major headaches getting the March 2009 release to work, I found it better to work with the December 2008 release.  Check your Microsoft SDKs folder in Program Files to find your files, this is the default install location for March 2009, for December 2008, you can store them wherever.

The Toolkit features controls such as AutoComplete, TreeView, DatePicker, Calendar, Pie and Bar charts (this is part of a whole data visualization package)and many others are all available.  In addition to the controls, the toolkit also contains themes which act much like skins in ASP .NET 2.0/3.5 and allow you to provide a consistent look to all the controls in your XAML file.  I enjoyed ShinyBlue and Twilight themes, as well as the Creme theme.

Finally, head over to the Microsoft Silverlight Learning Center and have Jesse Liberty talk you through using these controls.  If you get a chance I recommend checking out the DataForm video, this control will be available in Silverlight 3 and really makes my mouth water.  We use the data grid and repeater controls a lot in the applications we develop, and I cant tell you how nice it would be to replace using JavaScript for the interaction with C#.  So that makes me really excited, and combine with the Data Annotations package and you make developing data driven application in RIAs a snap.

Monday, June 08, 2009

Dependency Injection with MVC Framework (part 2)

In the first part of this we explored different strategies for using Entity Framework with the ASP .NET MVC Framework. We also discussed some of the weaknesses with existing models and how they do not meet our goals.  Now we will dive into using Dependency Injection as a means to get the Entity Framework data context instance to our business layer.  We want to maintain the ability to use one data context per request and make our model layer highly testable. We also want whatever method we decide upon to not create too many headaches for the developer and thus be easy enough to implement with a large amount of overhead; for this method we are taking the Dependency Injection route using Ninject.

This blog entry will not describe what Dependency Injection is, or how Ninject operates to accomplish it.  I will strive to arm you with the knowledge of what you must do to use Ninject with MVC as well as why we are doing what we are doing.  If you would like more information on Ninject, I suggest http://www.ninject.org.

To begin, what is necessary is that we intend to "inject" a single instance of our entity data context into a "service" layer.  This server layer is designed to hold our methods that will be referencing the entity data context.  If you think of it like this:

  • The View layer contains presentation information that is fed to it from the controller layer
  • The Controller layer dictates logical flow and is responsible for preparing the data before it is sent to the service layer. It is the traffic cop at the stop light
  • The Service layer, is implemented between the controller and model layer to act as a buffer and give us the ability to group related data methods.  An instance to each required service is created as a member for the controller. This allows us to list out a controllers dependencies very easily and effectively.
  • The model layer is responsible for creating an in-program representation of data from a data source and allowing us to work with data in a very object oriented fashion.

So lets see some sample code of what our controller could look like:

   1:  public class HomeController : Core.ControllerBase
   2:  {
   3:       [Inject]
   4:       public SeriesService SeriesService { get; set; }
   5:   
   6:       [Inject]
   7:       public StudioService StudioService { get; set; }
   8:   
   9:       public ActionResult Index()
  10:       {
  11:            ViewData["StudioList"] = StudioService.GetStudios();
  12:            return View(SeriesService.GetSeries());
  13:       }
  14:  }

So you will take note of the Service references, there is a StudioService and SeriesService.  Think of this as saying "the HomeController depends on access to both Studio and Series information".  So this is what provides access to the series and studio information for the actions within the HomeController.

The key thing to take note here is the Inject attribute, which tells Ninject that this is a dependency insert an instance here when the parent object is created.  So when MVC instantiates the HomeController it will "inject" instances of SeriesService and StudioService into the HomeController instance.

All of this does NOT happen by magic however.  Out of the box, you will get a NullReferenceException with this code.  This is because, while we have marked our code appropriately we are not actually using Ninject because the HomeController instance is still being created by MVC and not by Ninject.

To get around this we need implement our own ControllerFactory that MVC will use which uses Ninject to create the instances of our controllers, so that it is aware of the Inject attribute and how to handle it.  Below is an implementation of the ControllerFactory using Ninject that I am using:

   1:  public class NinjectCustomControllerFactory : DefaultControllerFactory
   2:  {
   3:       protected override IController GetControllerInstance(Type controllerType)
   4:       {
   5:            IKernel kernel = new StandardKernel(new MVCModule());
   6:            return (IController)kernel.Get(controllerType);
   7:       }
   8:  }

Next we need to actually tell MVC Framework to use this new controller factory; we do this by updating our Global.asax Application_Start method, as such:

   1:  protected void Application_Start()
   2:  {
   3:       RegisterRoutes(RouteTable.Routes);
   4:       ControllerBuilder.Current.SetControllerFactory(typeof (Core.NinjectCustomControllerFactory));
   5:  }

As I stated earlier, I am not going to explain how Ninject works or what this code does in depth.  It is sufficient to say that the Ninject kernel is used to create an instance of HomeController that is aware of the Inject attribute.  So what happens here is the HomeController (or any controller requested) is created through the Ninject kernel. Ninject will see the Inject attribute and add inject an instance of the dependencies into the class.

Now lets look at the SeriesService class:

   1:  public class SeriesService : INeedEntityManager
   2:  {
   3:       [Inject]
   4:       public AnimeManagerEntities EntityManager { get; set; }
   5:   
   6:       public Series GetSeries(int id)
   7:       {
   8:            return EntityManager.Series.FirstOrDefault(s => s.SeriesId == id);
   9:       }
  10:   
  11:       public List<Series> GetSeries()
  12:       {
  13:             return EntityManager.Series.ToList();
  14:       }
  15:  }

Notice the Inject attribute on the EntityManager, this is guaranteed by the INeedEntityManager interface.  I would normally put the Inject attribute in the interface, but it is here to save me from including more code.  Remember that we are charging Ninject with creating the HomeController.  When it creates the HomeController it will instantiate the instances of the Service classes defined as members for the Controller.  When it creates those Service members it will look for dependencies (things marked with Inject) in subsequent objects.  In this case, it notes a dependency on the AnimeManagerEntities data context instance.

So at this point we could leave this and the application will work just fine.  However, there is a problem with the default way Ninject handles this injection, in our case each service member will gain a UNIQUE instance of the data context.  We do not want this, we want the service members to share a common data context.  We can do this by configuring the bindings within Ninject.  The code below is the custom controller factory that we showed above:

   1:  public class NinjectCustomControllerFactory : DefaultControllerFactory
   2:  {
   3:       protected override IController GetControllerInstance(Type controllerType)
   4:       {
   5:            IKernel kernel = new StandardKernel(new MVCModule());
   6:            return (IController)kernel.Get(controllerType);
   7:       }
   8:  }

I want to point out line 8 and what is being passed to StandardKernel, this is a custom class whose implementation is shown below:

   1:  public class MVCModule : StandardModule
   2:  {
   3:       public override void Load()
   4:       {
   5:            Bind<ObjectContext>().ToSelf().Using<OnePerRequestBehavior>();
   6:        }
   7:  }

So, this is a demonstration of setting up bindings in Ninject.  In a nutshell this says, "for any object of type ObjectContext bind to yourself and use one ONE instance per web request.  This fixes the problem of the multiple data contexts in a request.

So lets review what happens with this solution: the MVC framework will read the URL provided and load a controller based on it.  We have overridden the default controller factory and used one of own which uses Ninject to create the controller instances. Because we are using Ninject and we have decorated our dependencies with the Inject attribute Ninject will cascade through the objects involved and fulfill any dependencies.  In the case of Entity Data Context instance we have a special case where we want to ensure there is only one context instance used per request.  The controller classes use the Service classes to talk to the models, those controllers then pass their data to the view layer where everything is displayed to the user.  We have a low degree of coupling and a high degree of testability.

Saturday, June 06, 2009

Dependency Injection with MVC Framework (part 1)

One of the problems I have had in the past with MVC is my data layer when I use one of Microsoft's ORM tools such as Linq2Sql or Entity Framework.  Here at RCM we tend to use the Kinetic Framework which is an ORM tool that is built on CodeSmith Templates and was developed in house.  However, as we continue to move forward there is a desire to choose a different direction due to new features and better support for existing databases.

One of the ORM tools I decided to look at and see how I could potentially use Entity Framework with the ASP .NET MVC Framework.  It went through quite a few evolutions but we ended up with a pretty decent solution, below are a few of the requirements the end solutions must meet:

  • We should have the ability to load data on demand either through eager loading or, more preferably, lazy loading.
  • We should be able to easy decouple our model layer from our web layer so that we can reuse the model layer in any context
  • We should be able to test the model layer independent from the View and Controller layers
  • The method should require minimal effort from developers to wire up the system and should not call them to make huge concessions with coding styles.
  • At most one entity context instance can be created per request and the reference must be thread safe (no static variables). It must also be destroyed at the end of the request

To begin, in my reading and watching of MVC tutorials I have seen the following code snippet used many times:

public class TestController : Controller
{
     private readonly AnimeManagerEntities entityContext = new AnimeManagerEntities();
     public ActionResult Index()
     {
          return View();
     }
}

So what this gives us is a entityContext for each Controller that we create.  In fact, this is not a bad idea, you could derive from Controller and create a public property that is given to all of your Controllers.

Using this approach you certainly can easily use the context variable to query the various data sets in the database.  If you trust Microsoft, you can have faith that the context will be closed, and because the context remains open during the call to View() which will allow lazy loaded properties in the View to be loaded on the fly.

So what is the problem with this approach...
Well its not very reusable, which is a huge problem for any large applications.  Consider if I had two actions, in this case we will have them in the same controller, each of which I need to grab a Series from the database based on a given id:

   1:  public class TestController : Core.ControllerBase
   2:  {
   3:       public ActionResult Index()
   4:       {
   5:            return View();
   6:       }
   7:   
   8:       public ActionResult Edit(int id)
   9:       {
  10:            return View(EntityContext.Series.Include("Studio")
  11:                 .FirstOrDefault(s => s.SeriesId == id));
  12:       }
  13:   
  14:       public ActionResult View(int id)
  15:       {
  16:            return View(EntityContext.Series.Include("Studio")
  17:                 .FirstOrDefault(s => s.SeriesId == id));
  18:       }
  19:  }

You will notice ControllerBase which provides the public property EntityContextControllerBase also has a custom destructor which disposes of the entity context variable.

The use of Include targets named relationships from the .edmx file and provides for eager loading, so that Series instances are extracted with the Studio reference loaded.

But the major problem here is code repetition.  In this simple example the same line of code is repeated twice. Imagine if this was a much more complex process with 20 or 30 actions.  What if we had to use this line all over the application and we suddenly wanted to change the order of Includes, or the primary key, or anything.  This harkens back to the reason why we create Model layers, to centralize the way we do things and improve the maintainability of code.  As I said, this solution will work fine for simple scenarios, but to use it with a larger project a different pattern must be used.

In addition, while the Controller is testable, the model layer is not.  This approach bleeds model and controller testing together as the Model is not properly decoupled from the Controller. Remember, the Controller shouldn't care how it gets the data from the mode, it just wants it. In the same respect, the View doesn't care how it was selected just that it was and the Controller provides the appropriate data that it needs.

So what we really need to do is centralize our data access logic so that we can test it apart from our controller logic. By doing so we can decouple the model layer and use it in other projects.

Now let us step back very quickly and understand something.  Regardless of the path we take we will want the EntityContext to come from the controller layer.   Saying this sounds like a contradiction to what I just said, it isn't, let me explain.

If we are feeding the context from the controller layer to the model layer, we are creating a dependency, not a rule. In testing we can certainly feed our model layer with an entity context. The entity context is NOT, however, tied to the controller layer as it was in the example above.  Given this principle we can rewrite the code as such:

   1:  public class TestController : Core.ControllerBase
   2:  {
   3:       public ActionResult Edit(int id)
   4:       {
   5:            return View(Series.GetSeries(EntityContext, id));
   6:       }
   7:   
   8:       public ActionResult View(int id)
   9:       {
  10:            return View(Series.GetSeries(EntityContext, id));
  11:       }
  12:  }
  13:   
  14:  // And in Series.cs
  15:  public partial class Series
  16:  {
  17:       public static Series GetSeries(AnimeManagerEntities context, int id)
  18:       {
  19:            return context.Series.Include("Studio")
  20:                 .FirstOrDefault(s => s.SeriesId == id);
  21:       }
  22:  }

This is not a bad solution. It is very testable and the code is centralized in what amounts to a basic ActiveRecord pattern.  However, we are now requiring developers to pass an instance of their EntityContext to EVERY SINGLE DATA METHOD.  By passing the reference to this method we are implying in code, that the developer must have a reference and it violates our tenant of not making it harder to code.  Furthermore, this adds unnecessary clutter to the method calls.

So we are close, the problem we want to solve now is how can we best get our reference into the model layer automatically without the developer worrying about it through a clean and well separated means that still permits loose coupling and high testability.  There are likely thousands of ways to achieve this, but I will show you an an example how I did it with Ninject Dependency Injection in the next part.

Tuesday, June 02, 2009

ASP .NET Ajax Authentication Services

Perhaps this is old hat to a lot of people, but I find it fascinating and damn useful. I have always liked the Membership services that are housed within .NET, its a perfect way to setup a login mechanism that is both customizable and secure, I tried to use it whenever I can to increase my familiarity with it.  Recently, I took a certification exam for Microsoft ASP .NET 3.5, while I unfortunately fell 1 question shy of passing the exam, it did show me that my experience with ASP .NET have been very limited.

One of the things that fascinated me was that Microsoft seemed to provide, through their Ajax framework, the ability to asynchronously log in via Ajax.  I found this hard to believe and really wanted to give it a shot. One of the effects I have always wanted to do more of is this asynchronous login, because I think it feels more natural to a person to be given a form and then login, rather then clicking login and going to a separate page.  Plus, using something like JQuery of event the MS Ajax client library you could easily update the existing page to reflect the admin view.

But enough of my ranting, how do you do it? Well to start a modification to the web.config is necessary to turn this on, add the following in your web.config:

<system.web.extensions>
    <scripting>
      <webServices>
        <authenticationService enabled="true" />
      </webServices>
    </scripting>
</system.web.extensions>

This enables it, the next step is to call it.  This, likewise, is very simple, though the method signature is quite long, and the documentation on the Microsoft site is backwards with a couple of the parameters:

Sys.Services.AuthenticationService.login("testUser", "testPass", true, null, "WebForm1.aspx", function(isValid, context, methodName) {
     debugger;
}, function(error, context, methodName) {
     debugger;
});

This signature can be broken down as such:

login(username, password, persistent, customInfo, redirectUrl, complete, fail)

Most of the parameters are fairly obvious in what they do, however, I will speak to a few of them, but mostly I recommend reading this page:

  • username: the username of the user logging in
  • password: the password of the user logging in
  • redirectUrl: if null, you stay put, if not null, you are redirect if the login is successful

It is worth mentioning that anytime the login function is SUCCESSFULLY invoked the login complete function is called. Supplied to the callback is a boolean IsValid parameter which denotes the outcome of the operation. The failCallback is called in the event the login function cannot be invoked.

Once again, the cool thing about this is that it integrates directly with the membership provider which can be defined by the developer and because it uses the provider pattern, can change freely without any major changes to your authentication logic. This represents a very flexible, secure, and maintainable login process.

References: