Monthly Archives: December 2011

Items Collection

The Items collection, which is a property of the Page class, has one particular quality that distinguishes it from the Session object. It only exists for the lifetime of a single request. That being the case, I’m not really sure what value it adds. If I needed an object in memory over the course of a Page’s life, I would just create a page variable, rather than add a value to the Items collection.

However, the Items collection which is a property of the Page object is different to the Items collection on the HttpContext.Current object. There is definitely a use case for this particular collection, which fills a particular niche.

If you are building one or more HttpModules and you would like to:

  1. store something in memory, but only for the duration of a single request;
  2. be able to retrieve that item in another HttpModule, or in the HttpHandler targeted by the request,

then the HttpContext.Current.Items collection is the way to go.

I’ve prepared a very simple example for download. In that example, there is a simple HttpModule which I have created called NameUserModule. I set a variable called NameOfMe in the HttpApp_BeginRequest event handler and I retrieve it in the Page_Load handler of the Default.aspx page (the targeted HttpHandler for the request).

ASP.NET Web Forms MVP

I like coding to patterns. And one pattern I really like is the Model View Presenter (MVP) pattern. Whilst the Patterns and Practices group’s implementation of this pattern (Web Client Software Factory) is good for big applications with a multitude of business modules, it is too heavy for smaller applications. This is where the ASP.NET Web Forms MVP project fills a niche nicely.

Put together by an Australian duo (Tatham Oddie and Damian Edwards), ASP.NET Web Forms MVP is a very nice implementation of the MVP pattern using the WebForms flavour of ASP.NET. With ASP.NET MVC all the rage these days, I like the fact that these guys went off and did their own thing, injecting new life into the WebForms universe. And they have incorporated messaging! Now that is really handy and feels like possible lessons learnt from some of the XAML technologies.

I have put together a really simple example to give you a taste. The charter I set for this example was to showcase the typical lifecycle of a request, starting at the View, going via the Presenter and hitting a data layer to retrieve some data from an XML file and display it in a grid (back on the View). There’s no paging or sorting on the Grid – unnecessary complexity for this style of example.

In the download code, you will find a solution with the following structure:

I have deliberately used the same prefix for the Logic and DataAccess projects (i.e. the name of the web project) as I have relied on convention for Presenter discovery.

Firstly, I need to create a model for my page:

public class DisplayAlbumsModel
{
	public List<Album> Albums { get; set; }
	public class Album
	{
		public string Id { get; set; }
		public string Artist { get; set; }
		public string Title { get; set; }
	}
}

This will provide the data context which I can hydrate in my Presenter and make available to my View.

Speaking of Views, I need an interface for the View:

public interface IDisplayAlbumsView : IView<DisplayAlbumsModel>
{
	event EventHandler RetrieveAlbums;
}

One event will do. This will be raised by the View to the Presenter, which will subscribe to it in its Load method. With composing components as the desired approach, we will now implement that View as a user control, over in the Webapp project. We will then chuck that user control on a very basic, bare-bones web page. The user control inherits from MvpUserControl<DisplayAlbumsModel>, strongly typed to my Model. It also implements IDisplayAlbumsView, raising the member event RetrieveAlbums in the Page_Load event handler:

public partial class DisplayAlbumsControl : MvpUserControl<DisplayAlbumsModel>, IDisplayAlbumsView
{
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!IsPostBack)
		{
			RetrieveAlbums(this, EventArgs.Empty);
			this.AlbumsGridView.DataSource = Model.Albums;
			this.AlbumsGridView.DataBind();
		}
	}

	public event EventHandler RetrieveAlbums;

	protected void AlbumsGridViewRowcommand(object sender, GridViewCommandEventArgs e)
	{
		// do stuff here. E.g. redirect to a page with details about the selected album.
	}
}

Finally, over to the Presenter back in the Logic project, which inherits from the WebFormsMvp.Presenter class, strongly typed to our View:

public class DisplayAlbumsPresenter : Presenter<IDisplayAlbumsView>
{
	private readonly ChinookDbHelper dataAccessHelper;

	public DisplayAlbumsPresenter(IDisplayAlbumsView view) : base(view)
	{
		dataAccessHelper = new ChinookDbHelper();
		View.RetrieveAlbums += View_RetrieveAlbums;
	}

	void View_RetrieveAlbums(object sender, EventArgs e)
	{
		List<DisplayAlbumsModel.Album> albums = new List<DisplayAlbumsModel.Album>(); // a collection of Domain objects.
		var albumsData = dataAccessHelper.GetAlbums(); // get the tuples from the Data Layer

		//  Transform the raw data to a collection of Domain objects.
		foreach (var album in albumsData)
		{
			albums.Add(new DisplayAlbumsModel.Album {Artist = album.Item3, Id = album.Item1, Title = album.Item2});
		}

		View.Model.Albums = albums;
	}
}

The presenter discovery is done by convention. To demonstrate what the framework looks for, all I have to do is add a Typo to the Presenter’s namespace. The stack trace tells the whole story. First it looks for the PresenterBinding attribute (more on that later). After that, it searches for it in certain namespaces:

AttributeBasedPresenterDiscoveryStrategy:
– could not find a [PresenterBinding] attribute on view instance ASP.controls_displayalbumscontrol_ascx

ConventionBasedPresenterDiscoveryStrategy:
– could not find a presenter with type name WebFormsMvpSimplePage.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.Presenters.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.Presenters.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.DisplayAlbums
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.Presenters.DisplayAlbums
– could not find a presenter with type name WebFormsMvpSimplePage.Presenters.DisplayAlbums
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.DisplayAlbums

So we can see how managing naming convention can be used to wire up the components of the MVP pattern.

If you want to use the PresenterBinding attribute for Presenter discovery, that is easily implemented by decorating the usercontrol class as follows:

[PresenterBinding(typeof(DisplayAlbumsPresenter), 
ViewType = typeof(IView<DisplayAlbumsModel>), 
BindingMode = BindingMode.Default)]

The attribute is the WebFormsMvp.PresenterBindingAttribute which has 3 properties: BindingMode, PresenterType and ViewType. Further examination of that attribute is beyond the scope of this post.

I’d like to thank Oddie and Edwards for this cool and light framework. Perfect for the scenario where you don’t want the overhead of the Web Client Software Factory, but you want the trimmings, familiarity and RAD aspects of Web Forms, plus the testability that the MVP pattern provides.

Download Code

Default Values and Settings

A really cool use of the jquery extend function is to implement default values in an object. One of the features of extend is that when it merges 2 objects, the properties of the new object, which have the same name as properties in the existing object, will supercede the properties of the existing object. This can be utilised to implement default values.

Lets say we have a business object which has a property Settings. And the Settings property has a number of properties. Now, we can pass in an object (lets call it options) which will have a set of properties. The idea being, the options object will be an object that the caller can configure to set the settings of our business object i.e. we will give the calling code the ability to set the Settings for the business object. The following code shows how we can do that. The commenting in the code explains what is going on:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

    <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <script type="text/javascript">

        //  This is the constructor function for our business object. It takes a parameter
        //  called options in to enable the calling code to set option values.
        function myBusinessObject (options) {

            var Settings = {
                closeWhenDone: true,
                color: 'blue',
                animation: 'slide'
            };

            //  Assign Settings to the prototype for the object, to create
            //  default values when the object is first created.
            this.prototype = Settings;

            // Use extend to override default Settings with options passed in.
            // Only those properties which have the same name will be superceded.
            $.extend(Settings, options);

            // This method is just to view the settings, for the purposes of this example.
            this.getSettings = function() {
                return Settings;
            };
        };

        function createObjectAndSeeSettings() {
            //  create a new business object, passing in an options object.
            //  Note that no value for animation is passed in. The default remains.
            var newObject = new myBusinessObject({ closeWhenDone: false, color: 'red' });
            var settings = newObject.getSettings();
            return settings.closeWhenDone + " " + settings.color + " " + settings.animation;
        }

    </script>

</head>
<body>
    <input id="ShowSettingsButton" type="button" value="Show Settings" onclick="alert(createObjectAndSeeSettings());" />

</body>
</html>

Note how the object being passed in does not include a property for animation. That being the case, the default value “slide” remains.

$.extend and Inheritance

I have written about how to implement inheritance in javascript in a couple of previous posts here, here and here. Today, I am going to look at one way which you can implement inheritance with jQuery.

There’s a jQuery method called extend. This method serves a wider purpose i.e. to Merge the contents of two or more objects together into the first object. However, you can use it to implement a certain kind of inheritance pattern. That is, one whereby the properties of one object are copied to another, augmenting that second object. Lets look at some code!

Similar to my previous examples, we will create a parent object called person and inherit from it using our “property copying” pattern:

        // using the object literal notation, create a person object
        var person = {
            legs: 2,
            arms: 2,
            getName: function() {
                return this.name;
            }
        }
			
        // Create an empty object, and add some properties to it. 
        // This will be the additional properties of the inheriting type.	
		var newBits = { };
		newBits.age = 37; 
		newBits.name = 'Dave';
        newBits.showAge = function() {
            return this.age;
        }

        // Create and pass into extend an empty object so as to preserve the state of the "person" object.
        // The "dave" object now contains all the properties of the parent (person) and the new properties in newBits.
		var dave = { };
		$.extend(dave, person, newBits); 

        function ShowAgeIfPresent(personLikeObject) {
            if (personLikeObject.age === undefined) {
                return 'Person has no age';
            }
            else {
                return personLikeObject.showAge();
            }
        }

Note that this is definitely a different inheritance pattern to the previous ones I have blogged about. For example, where a method is copied from the person object, every instance of the inheriting object will have its own copy of that method. Whereas, in the previous patterns, the method was stored once, in the prototype object, which every inheriting object would use.

So far, my favourite is the still new Object.create method. But this $.extend method is an interesting approach.

Here is the download code for this post.