Web Client Software Factory Automation

(This post was going to be posted a few weeks ago so the images are a bit outdated but the content is the same that you will see in latest drops)

I’ve been working on the Guidance Packages for the Web Client Software Factory. If you read this blog you probably know what is this all about. If not, in short we are adding functionality to Visual Studio 2005 to make the developer life easier :)

In the case of the Web Client Software Factory (WCSF from now on), in this first release we are targeting modularity, security and a testable programming model among other things.

In this drop you will see something really close to what we will be shipping.

Let’s deep into what the Guidance Package brings to the table.

First of all we will create a new web application and let’s call it “OrderManager”

wca1

wca2

Before creating the actual solution the recipe asks for a few things:

  • Where do you have the binaries (the new CompositeWeb Application Block and Enterprise Library Jan 2006)? I have compiled them and put them in c:\Lib
  • What’s the .net namespace that you will use for this application?

This is what we get after the solution is created:

wca3

In a nutshell:

  • A Website containing a default page, a default master page a default theme, references to the application blocks and EntLib.
  • A Shell module with a ModuleInitializer. This module will be used for pages that lives in the website root and some services initialization (like the SiteMapBuilderService and the EnterpriseLibraryAuthorizationService)

If you run the website at this point you will get this:

wca4

Adding a module…

We can add our first module by doing a right-click on the Modules solution folder.

wca5

The following feature is part of the “new generation” of guidance packages. Before you commit your module creation you can see what is going to happen to your solution (one project will be created, a folder on the website will be created, etc.)

wca6

The options are:

  • What’s the website project where you want to plug this module?
  • Do you want to have a different name for the folder on the website?
  • Finally we have an “Add test project” option that will create a VSTS test project for you with the Test Fixture for the DefaultViewPresenter

If we run the solution again we will see the new module plugged in the website

wca7

The cool thing about this is the loosely coupled model to add nodes to the sitemap. The OrdersModuleInitializer has a template method to register the sitemap nodes that the module will provide. Here we register the module site map node:

protected virtual void RegisterSiteMapInformation(ISiteMapBuilderService siteMapBuilderService)

        {

            SiteMapNodeInfo moduleNode = new SiteMapNodeInfo("Orders", "~/Orders/Default.aspx", "Orders");

            siteMapBuilderService.AddNode(moduleNode);                     

        }

(A nice addition to this would be a service that reads from the module web.config file and creates the corresponding nodes)

Adding a web page…

We can create pages for our module by right clicking on the “Orders” module folder on the website

wca8

We are leveraging the MVP (Model-View-Presenter) pattern. If you used the Smart Client Software Factory you should be familiar with this, if not you can read more about it here and here.

wca9

The view is separated in three parts:

  • The OrderListPresenter holds the logic for the view and has access to the view via an interface (IOrderList). This increases the testability of your applications. The idea is to have the view do almost nothing. Its responsibility will be to show stuff that the presenter wants and notify the presenter of user events (clicks, selects, etc.).
  • The IOrderList interface is the contract for the Presenter
  • Finally the OrderList.aspx + .cs is the actual implementation of the interface that will show things on the webpage.

If we want to show this view in the navigation control (in this case a TreeView) we would add the following code to the RegisterSiteMapInformation:

        protected virtual void RegisterSiteMapInformation(ISiteMapBuilderService siteMapBuilderService)

        {

            SiteMapNodeInfo moduleNode = new SiteMapNodeInfo("Orders", "~/Orders/Default.aspx", "Orders");

siteMapBuilderService.AddNode(moduleNode);                     

SiteMapNodeInfo orderListNode = new SiteMapNodeInfo("OrderList", "~/Orders/OrderList.aspx", "Order List");

            siteMapBuilderService.AddNode(orderListNode, moduleNode);

        }

Running the site at this instance will show the following:

wca10

Implementing a view and its presenter…

We will implement the basic things to show a list of orders on the web page.

Let’s start from the presenter logic. Note: If we were using TDD we would start from a test that would be called “ShowOrderListOnViewLoaded()”.

    public class OrderListPresenter : Presenter<IOrderList>

    {

        public override void OnViewLoaded()

        {

            // TODO: Implement code that will be executed every time the view loads

            List<Order> orders = new List<Order>();

            orders.Add(new Order("Order 1", 12300, DateTime.Now));

            orders.Add(new Order("Order 2", 200, DateTime.Now));

            orders.Add(new Order("Order 3", 100000, DateTime.Now));

            View.Orders = orders;

        }

We are setting the Orders of the View property. The View property belongs to the base Presenter class and it provides access to the view via its interface (IOrderList).
That means that we need to add the Orders property on the interface

    public interface IOrderList

    {

        IList<Order> Orders { set; }

    }

Finally we will implement it on the OrderList.aspx:

We can use the smart tag on the interface to generate the required interface contract:

wca11

Then we add the GridView to the page

wca12

And finally implement the interface:

    public IList<Order> Orders

    {

        set

        {

            GridView1.DataSource = value;

            GridView1.DataBind();

        }

    }

Running the site again…

wca13

That’s it. We have a Web application that leverages:

  • MVP design pattern
  • The best practices for ASP.Net
  • Exception handling using Enterprise Library 2006
  • Authorization infrastructure also from Enterprise Library
  • Dependency Injection
  • And a lot of other things that you will discover…

Lastly, if you are wondering about “Why use GridView.DataSource and not some DataSourceControl like ObjectDataSource?
We are shipping with the factory a DataSourceControl called ObjectContainerDataSource that will work very well in these scenarios. Mariano has an interesting post.

Published: December 12 2006

blog comments powered by Disqus