Wednesday, October 16, 2013

Building Unity.WebForms (Part 2 of 4)

In part 1 of this series, I talked about building the UnityHttpModule. Now that we have this HttpModule written, we need to register it with the ASP.NET pipeline to service requests.

Registering the UnityHttpModule

Traditionally, in order to register an HttpModule with the runtime you had to make a change to the web.config file. This was potentially prone to errors if it was placed incorrectly or you put it into the configuration section for IIS 7.0+ and not in the IIS 6.0 and earlier section.

Fortunately, Microsoft added support for just this scenario in the form of assembly 'pre-start' methods with the Microsoft.Web.Infrastructure assembly.

Step 1 - Create a PreApplicationStart class

Create a new class as follows:

public class PreApplicationStart
{
    private static bool _isStarting;

    public static void PreStart()
    {
        if ( !_isStarting )
        {
            _isStarting = true;
            DynamicModuleUtility.RegisterModule( typeof( UnityHttpModule ) );
        }
    }
}

This simple class defines a static method that will get run when the application is first starting up. It uses the Microsoft.Infrastructure.DynamicModuleUtility assembly to dynamically register an IHttpModule. Presto! Adding a DLL to a project can now automatically register itself when the application is starting up... no more copy-pasta with web.config!

Step 2 - Invoking PreStart() when the application starts

The only other step required is to tell the runtime to invoke the PreStart() method when the application is starting. To do that, simply add the following to the AssemblyInfo.cs file in your project:

using System.Web;

[assembly: PreApplicationStartMethod( typeof(Unity.WebForms.PreApplicationStart), "PreStart" )]

That's it!

Recap

Registering HttpModules (or HttpHandlers for that matter) is now really easy if you use the 'pre-start' methods from the Microsoft.Web.Infrastructure in your Assembly; no more mucking with web.config!

Monday, October 14, 2013

KnockoutJS and cross-model communication

I have been playing around with shifting ASP.NET MVC view processing from the server to the client in order to lighten the load on the web server. Doing this isn't really hard, all that you really need to do is have the server render an initial view and have the client request the data it needs via AJAX (MVC) or RESTful (WebAPI) calls back to the server. That's the easy part. Processing that data on the client and turning it into a functioning application with rich interactions is the harder part.

One approach that I have taken recently is to use the KnockoutJS library. In a nutshell, Knockout allows you to create a client-side view model that can be bound to your UI components and have them kept in sync automatically for you using 'data-bind' attributes on your html elements. It has been very easy to learn and has allowed for a fairly rich end-user experience without all of the 'find control, get control value, etc.' drudgery that comes with client-side processing. Take the short, in-browser tutorial to get a feel for how easy it is to get going with this small javascript library (15kb min+gz)!

Knockout supports the ability to bind your model to only a certain portion of your UI, which makes it really easy to build partial views in MVC that encapsulate a single piece of functionality that can be reused in multiple locations within your site. One problem that quickly becomes apparent when doing this is what happens when you have a page/view composed of multiple Knockout view models and you need to communicate between them (such as making an update in one panel and having another panel update simultaneously) without tight-coupling of the view models and breaking their independence?

What I have found recently is a Knockout extension called Knockout-Postbox. This extension allows for a messaging pub/sub mechanism (similar to amplify.js and postal.js) that leverages the existing framework in Knockout but can also be used with other, non-knockout, JS code.

I recommend checking it out and playing with it a little. It looks very promising at the moment for my needs.

Wednesday, October 09, 2013

Building Unity.WebForms (Part 1 of 4)

When ASP.NET WebForms was originally produced, it's design did not lend itself to easy dependency management. Despite dependency injection being a widely considered best-practice in other Object-Oriented languages like C++ or Java (the 'D' in S.O.L.I.D. design), it was not a widely held practice within the .NET community until recently.

When ASP.NET MVC started emerging as the new kid on the block, there was a concerted effort to implement a lot of industry best practices to allow for better separation of concerns, with a cleaner, more plug-able, and more test-able interface. For a lot of developers, this was their first exposure to the various methods of Inversion of Control (Service Location and Dependency Injection). The fact that the development of ASP.NET MVC was done in the open with help from the .NET community greatly helped ensure that this was the case.

In the ASP.NET MVC ecosystem, I stumbled across a nice little library called Unity.MVC3 created by DevTrends that put together a nice approach to using the new IDependencyResolver interface introduced in MVC3 along with the Unity container from Microsoft Patterns and Practices. Since I was already using various components of the Enterprise Library, of which Unity is a part of, this was a natural fit for me.

Since ASP.NET doesn't offer a built-in mechanism for dependency management, a different approach was required. What I found through online searches was that in the ASP.NET Request Pipeline, you could intercept the Page object at the point immediately after it was created but before any Page Life-cycle methods were called. During this window, we could walk the Page control tree and have Unity resolve any properties decorated with the [Dependency] attribute (property injection).

The UnityHttpModule

Due to the state-less nature of the web and the HTTP protocol, I needed a mechanism that would allow the objects resolved by the Unity Container to be unique for each request to avoid data from one user being confused with the data from another user. Imagine how upset you would be if Amazon ended up charging you for a new 80" Plasma TV when the only item you added to your cart was a DVD

Fortunately, Unity has a mechanism for producing Child containers from a singly configured Parent container. In order for this to happen though, we need to hook into the ASP.NET request pipeline and create a new child container near the beginning of each request. Something an HttpModule is well suited for.

The module

This module is mostly a verbatim copy of the code that can be found at the MSDN Patterns & Practices library.

Step 1 – Create a new HttpModule

Create a new Http Module, which is nothing more than a class that implements the System.Web.IHttpModule interface.

public class UnityHttpModule : IHttpModule
{
}

When implementing this interface, there are two methods that need to be defined: Init() and Dispose(). Since our implementation of the module will not be holding onto any unmanaged resources directly, we only need to provide an implementation of the Init() method as follows:

/// <summary>
///     Initializes a module and prepares it to handle requests.
/// </summary>
/// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, 
///     properties, and events common to all application objects within an ASP.NET application </param>
public void Init( HttpApplication context )
{
    context.BeginRequest += ContextOnBeginRequest;
    context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
    context.EndRequest += ContextOnEndRequest;
}

This method is short and focused, registering the module to handle three different events:

  • BeginRequest - Creates a new child container from the parent container.
  • PreRequestHandlerExecute - This event occurs before the ASP.NET runtime starts executing an event handler, like a Page or a Web Service.
  • EndRequest - Disposes of the child container to ensure resources are properly garbage collected.

Step 2 - Create the child container for the request

The OnBeginRequest method simply creates a new child container from the parent container so that each web request gets it's own instances of the registered types.

private void ContextOnBeginRequest( object sender, EventArgs e )
{
    ChildContainer = ParentContainer.CreateChildContainer();
}

where the ParentContainer and ChildContainer properties are defined as follows:

private IUnityContainer _parentContainer;

private IUnityContainer ParentContainer
{
    get { return _parentContainer ?? ( _parentContainer = HttpContext.Current.Application.GetContainer() ); }
}

private IUnityContainer _childContainer;

private IUnityContainer ChildContainer
{
    get { return _childContainer; }

    set
    {
        _childContainer = value;
        HttpContext.Current.SetChildContainer( value );
    }
}

More information about child container usage in Unity can be found here: Using Container Hierarchies.

Step 3 - Determine if this is a request that needs to built up

The OnPreRequestHandlerExecute event handler is fired just prior to the request being handled by the ASP.NET runtime and is defined as follows:

private void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
    /* static content; no need for a container */
    if ( HttpContext.Current.Handler == null )
    {
        return;
    }

    var handler = HttpContext.Current.Handler;
    ChildContainer.BuildUp( handler.GetType(), handler );

    // User controls are ready to be built up after the page initialization in complete
    var page = handler as Page;
    if ( page != null )
    {
        page.InitComplete += OnPageInitComplete;
    }
}

First, we need to check if the current request is for a static resource (in which case the Http Context Handler will be null) or something that the ASP.NET runtime would be involved with handling. If this is a request that will be handled by ASP.NET, then we get an instance of the child container, have it build-up the current HTTP handler, and register an event handler for the page InitComplete event.

Step 4 - Build up the control tree

The page InitComplete event is raised immediately after the page object has been instantiated, but prior to the page life-cycle events being raised. At this point, we have a chance to perform property injection on the page and any nested controls. The body of the OnPageInitComplete event handler is defined as follows:

private void OnPageInitComplete( object sender, EventArgs e )
{
    var page = (Page)sender;

    foreach ( Control c in GetControlTree( page ) )
    {
        var typeFullName = c.GetType().FullName ?? string.Empty;
        var baseTypeFullName = c.GetType().BaseType != null ? c.GetType().BaseType.FullName : string.Empty;

        // filter on namespace prefix to avoid attempts to build up system controls
        if ( !typeFullName.StartsWith( "System" ) || !baseTypeFullName.StartsWith( "System" ) )
        {
            ChildContainer.BuildUp( c.GetType(), c );
        }
    }
}

Here we walk the control tree for the page and have the child container build up each control. In order to prevent a lot of potential reflection overhead for controls that have not been authored by you, we limit the build up action to only controls that are not defined in the System.*namespaces. This could be further optimized in your own project by only looking for namespaces that you control, but in order to make this into a universal NuGet package that others could use, I simply took the route of filtering out the System namespace.

The GetControlTree() method (shown below) is just a wrapper around recursively walking the control tree.

private static IEnumerable GetControlTree( Control root )
{
    if ( root.HasControls() )
    {
        foreach ( Control child in root.Controls )
        {
            yield return child;

            if ( child.HasControls() )
            {
                foreach ( Control c in GetControlTree( child ) )
                {
                    yield return c;
                }
            }
        }
    }
}

Step 5 - Clean-up

The ContextOnEndReqesut method gets called at the tail-end of the request pipeline and allows us to properly dispose of the child container, which in turn disposes of all objects registered in the container.

private void ContextOnEndRequest( object sender, EventArgs e )
{
    if ( ChildContainer != null )
    {
        ChildContainer.Dispose();
    }
}

Recap

In this post, we saw how to create an HTTP Handler that will intercept the constructed Page/Control just before any life-cycle events are fired allowing us to inject any dependencies from our container (Unity).

In the next post, we will see how to register this new Handler into the request pipeline without having to edit the web.config file.

Tuesday, October 08, 2013

Reboot (v2)

Despite earlier efforts at keeping this blog up-to-date, it always seemed that there was not enough time in the day/week to post regular updates. I tried posting small snippets of things that I had found/discovered that others might find useful, but I didn’t want to turn this blog into a ‘link only aggregator’. I wanted to add my own thoughts on it to make it more personal.

That said, I’m going to give this another go and see what happens. I will start with a small series of posts about building a small NuGet package that I have put together and released upon the world, Unity.WebForms.

Time to brush off the rust, oil the joints, and get this blog moving again!