Web Client Software Factory Automation
December 12th, 2006
(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”
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:
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:
Adding a module…
We can add our first module by doing a right-click on the Modules solution folder.
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.)
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
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
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.
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:
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:
Then we add the GridView to the page
And finally implement the interface:
public IList<Order> Orders
{
set
{
GridView1.DataSource = value;
GridView1.DataBind();
}
}
Running the site again…
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.
A picture with Bill Gates
December 4th, 2006
It was the last week during the Strategic Architecture Forum (SAF) here at Redmond.
More than 250 architects from all over the world assisted to this event where Billg gave a 90 minutes Q&A session among other great presentations by the Architecture Strategy Team. Wojtek from patterns & practices presented CAB and the Smart Client Software Factory. Also there was lots of Software as a Service content
From left to right: Matias Woloski, Bill Gates, Eric Rudder (behind) and Mariano Szklanny