The conception, birth, and first steps of an application named Charlie

Subscribe: Atom or RSS

The WebContext Object

by Alister Jones (SomeNewKid)

In an earlier weblog entry concerning the Web System, I described how I planned to keep the Runtime Layer as close as possible to the ASP.NET runtime. One of the most important objects in ASP.NET’s runtime, if not the most important object, is the HttpContext object. The documentation tells us that the HttpContext object “encapsulates all HTTP-specific information about an individual HTTP request.” The HttpContext object encapsulates information about the incoming request, the outgoing response, the current user, the current session, and everything else needed to handle the incoming request.

To mirror the functionality of the HttpContext object, I created in Charlie’s Runtime Layer a WebContext object:

namespace Charlie.Framework
{
    // *******************************************************
    //  WebContext Class
    //
    /// <summary>
    /// The WebContext provides details of all information 
    /// and objects needed for Charlie and its plugins  to
    /// respond to a user's HTTP request.
    /// </summary>
    /// <remarks>
    /// Mimics the intrinsic HttpContext class.
    /// </remarks>
    //
    // *******************************************************
    public class WebContext
    {
    }
}

Why not just use the built-in HttpContext object, and add any extra information into its Items property? The reason is that the intrinsic HttpContext object only exposes those objects it knows about, such as the User. It obviously cannot expose those objects that are specific to Charlie, such as the website’s Owner and the website’s Domain. This means that some objects would be exposed “normally,” and other objects have to be retrieved from its Items collection, like this:

User user = HttpContext.Current.User;
Owner owner = (Owner)HttpContext.Current.Items["Owner"];
Domain domain = (Domain)HttpContext.Current.Items["Domain"];

This sort of inconsistency can lead quickly to complexity. Moreover, it requires that all consuming code know the collection key to use to retrieve an item, which makes the code brittle to any changes in the Items collection. So, I elected to give Charlie its own WebContext object that worked the same way as HttpContext, but that exposed all interesting objects in precisely the same way. Therefore, the above code can be simplified:

User user = WebContext.Current.User;
Owner owner = WebContext.Current.Owner;
Domain domain = WebContext.Current.Domain;

What I liked about this approach is that it brought together, in one place, all interesting context objects. Without the WebContext object acting as a kind of sheperd, all these objects would be running about in different directions, all requiring different ways of grabbing hold of them (some may be in HttpContext.Current.Items, some may be attached to the executing thread, and some may be floating about in memory, not being attached to anything at all). Because I liked this neat collection of interesting objects, I extended it to provide access to objects that must normally be grabbed from other locations. For example, the WebContext object exposes the current Thread, and exposes the Culture of the thread. I’m sure the Law of Demeter would have something to say about this approach, but the WebContext object is just so handy that it would seem foolish to sacrifice its simplicity to the gods of object-oriented development.

The only question that remained is where to store this handy object? My first inclination was to store it in a slot of the current thread. Do I actually know what I just said there? Nope—no idea. All I know is that the clever boffins at Telligent store their CSContext object in that location. Further, I liked the idea that if ASP.NET stores its HttpRequest and HttpResponse and so on in HttpContext, Charlie’s WebRequest, WebResponse, and WebContext would be stored in a different location: the thread. However, I was then told that in certain circumstances, a current web request will “jump” to another thread. ASP.NET will move across the HttpContext object, including anything in its Items property, but it will not move across anything stored in the slot of the old thread. All this really means is that in rare circumstances, my dear WebContext object would be left behind like an unloved pet. So I elected to instead store my WebContext object in the Items property of the HttpContext object, so that it would never be left behind, and would instead always travel with ASP.NET’s own HttpContext object.

Anyway, the WebContext object has proven to be very interesting and very useful, even if the above description is truly boring. (Sorry about that.)

by Alister Jones | Next up: The WebAddress Object

0 comments

----