Table of contents
Introduction and goal
All application UI have common logics like navigating to the next UI, state management, and work flow. By putting all the three logic in the code itself, you tie up all the three aspects with a specific UI type like Windows or web. This article will discuss how we can use UIP to achieve UI portability.
Other application blocks
- Validation application blocks: This article explains the 16 steps you need to perform to do validations using VAB: Validation application blocks.
- Client-side validation: One of the short comings in VAB is that it does only server side validations. This article talks how we can leverage VAB for the client side: Client side validation.
- Dynamic validation: This article explains how to build dynamic validation on a scenario basis: Dynamic validation.
- Policy application blocks: This article talks how to implement a plug and play mechanism using Policy application blocks: Policy application block.
- Logging application block: This article explains the 5 basic steps of how to use logging application blocks: Logging application block.
- Data application: This article talks about the four steps you need to implement data application blocks: Data application block.
- Exception application block: This application talks how we can use exception application blocks to log exceptions from a project: Exception application block
- Unity application block: This application talks about Unity application block in DI and IOC: Unity application block.
The problem
Decoupling the navigation and workflow from a user interface type is a challenge by itself. In short we are talking about putting the navigation and workflow 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 that comes to our mind is using MVC. So we centralize all our workflow 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 the paper. Let’s see how we can achieve the same practically. So below is the navigation which we want on both Windows and web.
Above is how the navigation and workflow will look like in web.
Above is how the navigation and workflow will look in a 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 the 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 a 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 to 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 it in web.config, and if it’s a Windows application, you need to define it 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 the 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 the navigation graph, we need to refer the views with view names. So we have made Homeview
as the start view. When we specify a navigate value, the view navigates to the 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 if 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 the ControllerBase
class. We have exposed methods and functions which can be called by a web application or a Windows application. These methods set the state value to the navigate value and then we call the navigate method. Depending on the config file, the 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 GoToHome
. With this, the page will transition to the next view, i.e., the Home.aspx in the WebForm and Home.cs in Windows.
((clsController)(this.Controller)).GoToHome();
You can download the source code of the above sample from the link at the top of this article.
So should you use it and what’s the future of UIP
In case you need to make workflows and navigation portable across UI, this solution can be looked into. I say can be looked into. We have implemented UIP in a project as we needed the navigation and workflow to be synchronized both for web and Windows. We successfully implemented the project but it had its pains. Thanks to Tom Hollander, who has summed up the practical issues of this block: http://blogs.msdn.com/tomholl/archive/2005/03/01/383330.aspx.
- The block has now moved to the archive which means Microsoft will not support it any more. Looks like the team has abandoned it.
- Many things are not fully automated so playing around with config files 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 a confusion. The next version should have a clearer implementation targeting Windows and web UIs.
- No good web samples. 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 code from this link: Click here.
It has the MyController project which has the generalized controller and I have utilized the controller in both web and Windows applications.
For further reading do watch the below interview preparation videos and step by step video series.