Saturday, September 12, 2009

Reusable Navigation and workflow for both Windows and Web using Microsoft UIP blocks

Introduction and Goal


All application UI have common logics like navigating to the next UI, state management and work flow. By coding all the above three logic in the code itself you tie up all the three aspects with a specific UI type like windows and web. This article will discuss how we can use UIP to achieve the UI portability.
Please feel free to download my free 500 question and answer videos which covers Design Pattern, UML, Function Points, Enterprise Application Blocks, OOP'S, SDLC, .NET, ASP.NET, SQL Server, WCF, WPF, WWF, SharePoint, LINQ, SilverLight, .NET Best Practices @ these videos http://www.questpond.com


Reusable Navigation and workflow for both Windows and Web using Microsoft UIP blocks


The problem
Approaching the problem using MVC
The (UIP) User Interface Process application block
Download and Install UIP block
Making it ready for VS 2005—The XSD fix
The Navigation graph
WebFormView and WindowsFormView
The generalized controller
The start page
So should you use it and what’s the future of UIP
The source code

The problem

Decoupling the navigation and work flow from a user interface type is a challenge by itself. In short we are talking about putting the navigation and work flow in one class and then using it to drive any kind of UI type i.e. Web or Windows. Below is a pictorial representation of the concept.



Approaching the problem using MVC

One obvious approach comes to our mind is using the MVC. So we centralize all our work flow and navigation logic in the controller and let the controller drive the UI navigation irrespective of the user interface type.


This is nice and theoretical to be discussed on paper let’s see how we can achieve the same practically. So below is the navigation which we want on both windows and web.

So above is how the navigation and work flow will look like in web.

Above is how the navigation and workflow will look in windows application. So our target is to make a centralized navigation which can be reused for both windows and web.

The (UIP) User Interface Process application block

Below points I have shamelessly copied from the UIP block help.
The User Interface Process (UIP) Application Block, version 2, provides an extensible framework to simplify the process of separating business logic code from the user interface. You can use the block to write complex user interface navigation and workflow processes that can be reused in multiple scenarios and extended as your application evolves. The UIP Application Block addresses a specific set of challenges that you will encounter in user interface development. These include:

• Navigation and workflow control – This should not be embedded in the user interface, but often is because the decision about which view to display next is based on business logic. This results in inelegant and unmanageable code.

• Navigation and workflow changes – Reformatting the layout of an application (changing the sequence of pages or adding new pages) is very difficult with traditional user interface techniques.

• State management – Passing state and maintaining consistency of state between views is difficult and is different for Windows-based applications and Web applications.

• Saving a snapshot of current interaction – You may want to capture a snapshot of an interaction and recreate it elsewhere, across time, machine, or logon boundaries.

Download and Install UIP block

The first thing you need to do is download the UIP block. We will be using the 2.0 version of UIP.
http://www.microsoft.com/downloads/details.aspx?FamilyId=98C6CC9D-88E1-4490-8BD6-78092A0F084E&displaylang=en

Making it ready for VS 2005—The XSD fix

Once you install you should see Microsoft application for .NET in your program files. UIP was made for VS 2003 which causes some serious defects in VS 2005. So we will first fix them up. You need compile the UIP block by removing the following line from the UIPConfigSchema.xsd file.
<xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip" />


Once done you are all set to use the UIP in .NET 2.0. Thanks to tannerel for this fix helped me out http://forums.asp.net/t/713774.aspx

The Navigation graph

All the navigation in UIP block is defined in the config file. So if it’s a web application you need to define the same in web.config and if it’s a windows application you need to define the same in app.config.

First thing we define the view names and the related UI page with the same. So below is the views section for web application. We have five views ‘Home.aspx’,’LogOut.aspx’,’CustomerHom.aspx’,’DisplayCustomerWithSales.aspx’ and ‘DisplayCustomerWithOutSales.aspx’.
<views>
<view name="HomeView" type="Home.aspx" controller="MyController"/>
<view name="LogOutView" type="LogOut.aspx" controller="MyController"/>
<view name="CustomerView" type="CustomerHom.aspx" controller="MyController"/>
<view name="CustomerSalesView" type="DisplayCustomerWithSales.aspx" controller="MyController"/>
<view name="WithOutSalesView" type="DisplayCustomerWithOutSales.aspx" controller="MyController"/>
</views>


For windows we link it with a form. The same views in the App.config file are linked with the windows form class. One of the points to be noted is that the views are tied up with the controller.
<views>

<view name="HomeView"   type="WindowsUIPExample.Home,
WindowsUIPExample, Version=1.0.0.0,
Culture=neutral,PublicKeyToken=null" controller="MyController" stayOpen="true"/>

<view name="LogOutView"   type="WindowsUIPExample.LogOut,
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController"/>

<view name="CustomerView" type="WindowsUIPExample.CustomerHome,
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController"/>

<view name="CustomerSalesView" type="WindowsUIPExample.CustomerWithSales,
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController" />

<view name="WithOutSalesView" type="WindowsUIPExample.CustomerWithOutSales,
WindowsUIPExample, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null" controller="MyController"/>

</view>


Now we need to define the navigation using the navigation graph. In navigation graph we need to refer the views with view names. So we have made the ‘Homeview’ as the start view. When we specify a navigate value the view navigates to next view depending on the node where it’s present. In other words if the state is ‘Homeview’ and we set the navigate value to ‘LogOut’ it will move to the ‘LogOutView’ i.e. ‘LogOut.aspx’.
<navigationGraph startView="HomeView" iViewManager="WindowsFormViewManager" name="MyNavigationGraph" state="State" statePersist="MySession">
<node view="HomeView">
 <navigateTo navigateValue="LogOut" view="LogOutView"/>
 <navigateTo navigateValue="GoCustomerHome" view="CustomerView"/>
</node>

node view="LogOutView">
 navigateTo navigateValue="GoToHome" view="HomeView"/>
/node>
<node view="CustomerView">
 <navigateTo navigateValue="GotoHome" view="HomeView"/>
 <navigateTo navigateValue="WithOutSales" view="WithOutSalesView"/>
 <navigateTo navigateValue="ViewSales" view="CustomerSalesView"/>
</node>
<node view="WithOutSalesView">
 navigateTo navigateValue="GoCustomerHome" view="CustomerView"/>
</node>
<node view="CustomerSalesView">
 navigateTo navigateValue="GoCustomerHome" view="CustomerView"/>
</node>
</navigationGraph>




WebFormView and WindowsFormView

If it’s a windows form you need to inherit from ‘WindowsFormView’ and it’s a web application you need to inherit from ‘WebFormView’.

The generalized controller

Below is the code snippet of the magical controller. In UIP the controller should inherit from ‘ControllerBase’ class. We have exposed methods and function which can be called by web application or windows application. These methods set the state value to the navigate value and then we call the navigate method. Depending on the config file controller navigates to the next UI.
public class clsController : ControllerBase
{
        public clsCustomers objCustomers = new clsCustomers();

        public clsController(Navigator objNavigate)
            : base(objNavigate)
        {
            objCustomers.LoadCustomers();
        }
        public void GoToLogOut()
        {
            this.State.NavigateValue = "LogOut";
            this.Navigate();
           
        }
        public void GoToHome()
        {
            this.State.NavigateValue = "GoToHome";
            this.Navigate();
           
        }
        public void GoCustomerHome()
        {
           
            this.State.NavigateValue = "GoCustomerHome";
            this.Navigate();
        }
        public void GoToWithOutSales()
        {
          
          
            this.State.NavigateValue = "WithOutSales";
           
            this.Navigate();
        }
        public void GotoWithSales()
        {
            this.State.NavigateValue = "ViewSales";
            this.Navigate();
        }
}

The start page

You always need to define a start page which will start the navigation. The start page should be a simple web or windows application. It should not inherit from ‘WebFormView’ or ‘WindowsFormView’. In the start page we need to just call the navigation name.
UIPManager.StartNavigationTask("MyNavigationGraph");


In the UI we need to get hold of the controller and call the appropriate function to navigate. For instance in the below code snippet we have called the ‘this.controller’ type casted it and called the ‘GoToHome’. With this the page will transition to next view i.e. the ‘Home.aspx’ in webform and ‘Home.cs’ in windows.
((clsController)(this.Controller)).GoToHome();


You can download the source code of the above sample which is attached with this article at the end of the tutorial.

So should you use it and what’s the future of UIP

In case you need to make work flows and navigation portable across UI this solution can be looked in to. I say can be looked in to. We have implemented UIP in a project as we needed the navigation and workflow to be synchronized both for web and windows. We have successfully implemented the project but it had its own pain. Thanks to Tom Hollander to sum up the practical issues of this block http://blogs.msdn.com/tomholl/archive/2005/03/01/383330.aspx.

I will just put the same in bullet points: -

• The block is now moved to the archive which means Microsoft will not support it any more. Damn looks like the whole team is abandoned.

• Many things are not fully automated so playing around with config file is really a pain.

• Many architects still think that controllers cannot be generalized as the behavior of web and windows are very much different.

• The way UIP is applied it works against the ASP.NET architecture.

• The approach is of MVC but somewhere they have created confusion. The next version should have clearer implementation targeting windows and web UI.

• No good web samples. Some complicated samples will really help out. I think if you search google the only web sample for UIP you should find is this article…just praising myself. Microsoft examples are like toys….

The Source code

You can get the above code, For link Click here
It has the MyController project which has the generalized controller and I have utilized the controller in both web and windows application.

No comments: