Today’s software applications require an enterprise architecture that considers security, scalability, performance, reusability, and maintenance. Microsoft promotes a layered distributed architecture along with a library of best practice application blocks that satisfies these requirements. In particular, the User Interface Program Application Block provides a reusable, extensible framework for constructing the presentation layer for a Web and/or Desktop application.
The primary goal of this article and its samples is to provide a primer to the User Interface Application Block, encourage its use, and to equip developers to educate themselves further using Microsoft’s documentation. Secondarily, this article provides a brief introduction to Microsoft’s Application Architecture for .NET and their Application Programming Blocks.
This article and the samples assume Microsoft Visual C# .NET 2003.
Microsoft’s approach to developing distributed enterprise applications is to partition the application into layers of encapsulated components and services that, together, provide the application’s functionality. To accomplish this, Microsoft suggests a message based architecture that relies on collaborating software components and services exposing business processes through their interfaces. All requests for business processes must go through the component’s interface.
A software component provides a business process through its interface.
Related components are logically grouped to form layers of functionality. Most software developers are familiar with a common Enterprise Pattern that separates an application into Presentation, Business and Data layers. Each layer contains collaborating software components that provide services that implement programming patterns and practices common to each layer type. The Presentation Layer manages user interactions, the Business Layer implements business rules, and the Data Layer accesses data sources.
Microsoft uses the term “layer” to refer to a group of related component types and uses the term” tier” to refer to physical distribution patterns.
The benefits of a layered architecture are several. Some of them are:
- Complexity is encapsulated from the consumer of the service.
- By providing consistent interfaces, components and services can reside on any machine, anywhere in the world.
- Developers can work on several layers of the application in parallel.
- Each layer can provide additional security.
- The components and services are reusable by client applications or other services regardless of their implementation.
Applications, then, become an integrated set of cooperating components and services rather than a collection of a few monolithic programs that combine the data access logic, user interface navigational code, and business logic into a single executable.
Microsoft’s Patterns and Practices web site provides valuable guidance and source code to develop .NET layered applications. Specifically, the application blocks contained in the Enterprise Library provide plug and play functionality that address common programming practices in multi-layered applications.
The application blocks that comprise the Enterprise Library are:
- Caching Application Block.
- Configuration Application Block.
- Data Access Application Block.
- Cryptography Application Block.
- Exception Handling Application Block.
- Logging and Instrumentation Application Block.
- Security Application Block.
Currently, no application block exists in the Enterprise Library that manages the Presentation Layer. Still, developers are not left on their own as Microsoft provides a separate, freely downloadable application block for the Presentation Layer. While not yet included with the Enterprise Library, the block’s reusable and extensible features are consistent with other application blocks that make it a worthwhile addition to the Enterprise Library.
The Presentation Layer contains the user interface components – forms and views – and the user process components – navigation and state management - that enable user interaction with the application. In many Web and Desktop applications, the user interface logic is included with the user process component logic. In other words, the code that controls the navigation and state from one form to another is tightly coupled with the code that presents the user interface.
Coupling the navigation code with the user interface code makes it difficult to change one without changing the other. It also prevents reusability since each form contains its own navigation logic. A more reusable approach would be to separate the navigation logic from the user interface logic in order to share the navigation logic amongst all the forms of the application - even reused in other applications.
Moreover, many forms maintain their state internally. This hinders reusability and extensibility of the application since the form must be accessed to obtain its state. If the form’s state management were decoupled from the form and shared with other forms, the application could be stopped and restarted to any form where the user left off. Additionally, if the form’s state is maintained outside the form, a new form could be inserted into the navigation sequence with little impact, if any, to the existing forms.
Decoupling the navigation and state management logic from the form would enable the Presentation Layer to be extensible and reusable.
A framework that provided these capabilities would be a tremendous aid to developer productivity.
The User Interface Program Application Block version 2.0 (UIPAB) presents a reusable, extensible framework for constructing the Presentation Layer for a Web and/or Desktop application. It accomplishes this by separating the user interface logic from the user process logic. That is, the code that displays the user interface is separated from the code that manages the navigation flow and state management.
But that’s not all it does. Among others, the UIPAB also offers these features:
- Task restartability that allows users in Web and Desktop applications to save their information and resume at a later time where they left off.
- State persistence that permits application state to be stored and retrieved from variety of sources: database, web session, memory.
- Session Portability that enables web sessions to be suspended and resumed on a different device.
- Wizards that foster the rapid development of wizard interfaces
The UIPAB implements these features by using a variation of the Model-View-Controller design pattern.
The UIPAB facilitates the development of a reusable, extensible Presentation Layer by decoupling the navigational and state management code from Web and Desktop forms.
So, how is it used? The key to understanding the UIPAB is to understand the role of its four main elements:
- Custom Controller
- Configuration file
For the most part, the configuration file and the UIPAB Custom Controller are the main elements that work together to abstract the Navigation and State management logic from the user interface code. They form the heart of the UIPAB.
In UIPAB terms, a view is simply the user interface component – the form - that is displayed to the user. Technically, it’s the View in the Model-View-Controller pattern. Views navigate to other views as a result of a transition. For instance, clicking a “Next” button in a view might cause a transition to another view. The UIPAB documentation defines the transition between views as the Navigation Graph. The Navigation Graph defines the allowed transitions from one view to another. Consider the following figure.
In figure 5, the transition paths are determined by “next” and “continue”. View 1 navigates to View 2 when the transition labeled “next” occurs. View 2 navigates to View 3 when the “continue” transition occurs. The “next” and “continue” transition values are mapped to the view via the configuration file.
The UIPAB controller is responsible for view navigation and provides the central location for accessing the Presentation Layer’s shared state. It represents the controller in the Model-View-Controller design pattern.
Whenever one view navigates to another view, it does so through the controller. For example, a Web view that doesn’t use the UIPAB might navigate to another Web view using the following code snippet:
In contrast, a view that uses the UIPAB might navigate to another Web view using the following code snippet:
The UIPAB snippet displays the exact same view, but notice the name of the view is unspecified. The name of the view is obtained from the configuration file from the UIPAB framework. Furthermore, the name of the method in the controller, in this case,
Transfer(), is completely arbitrary. Any method name would suffice as long as the method is mapped to the correct view. This mapping also occurs in the configuration file.
By abstracting the view name and the navigation logic from the View code, the controller can be shared by a Desktop or Web application.
The UIPAB State class represents the Model in the Model-View-Architecture. The state is shared between all the views and controllers interacting in a single task (a task is an executing instance of the UIPAB) and applies to the Presentation Layer only – not to the application’s business objects. Persistence is provided by a variety of sources such as SQL Server, memory and ASP.NET Session implementations. Views can be notified when the state changes.
The UIPAB provides a default state management class that will suffice for many, if not most, applications.
The configuration file defines the views, their state management, the navigation between them, and their controllers. It maps and unifies all four of the UIPAB’s major elements.
For Web applications, the configuration file is web.config. For Desktop applications, the configuration file is app.config. These are the same files that .NET applications already use, but, to use the UIPAB, a new section must be added to the configuration file that maps the views to the controller.
Note: All views in the application don’t have to be specified in the configuration file; the UIPAB can coexist with views that don’t use it. For example, it might be desirable to launch a UIPAB based Wizard from a non-UIPAB based view. Upon completion of the Wizard, the application can resume executing without using the UIPAB.
The forms in the sample applications that are prefixed with “Form”; ex: “Form1” do not use the UIPAB.
The forms in the sample applications that are prefixed with “View”; ex: “View1” do use the UIPAB.
Putting it all together
The three sample projects developed for this article demonstrate the use of the UIPAB functionality with a Web application, a Desktop application and a Wizard. They are very simple and demonstrate the most basic functionality. Use them as a foundation to build on. By experimenting with the samples, the Microsoft documentation will lead you to more advanced functionality.
The samples are contained in a folder called SimpleUIPAB.
To begin, open the SimpleWebUIPAB or the SimpleWinUIPAB project. Open the following files:
- The configuration file
Refer to each of the above, as necessary, throughout the remainder of the article.
Here are the steps to develop an application that uses the UIPAB.
- Download, install and compile the UIPAB. Version 2.0 of the UIPAB is available here.
- Using Visual Studio.NET create the Web or Desktop project and add a reference to the UIPAB assembly. This is normal .NET procedure. Create the project and reference the external assembly.
Add the following directive at the top of the file:
- Develop the application views from use cases.
Analyze the project’s use cases to develop the application views. Understand the transitions to and from each view and label each. These transitions will define the navigation flow.
- In each view, inherit from the
WindowsFormView class, depending on your application.
Each view in the navigation graph must inherit from a UIPBAB form view.
public class View1 : WebFormView
public class View1 : WindowsFormView
- Modify the configuration file.
Web applications use web.config. Desktop Applications use app.config. If needed, create the app.config file from the “Add New Item” menu in Visual Studio .NET.
The UIPAB’s configuration section must be added to the
<configSections> of the configuration file. If
<configSections> doesn’t exist, create it.
Next, add the
<uipConfiguration> section that defines the views, navigation graph, state management and controllers used by the application. Web and Desktop applications have different settings but the general structure of the
<uipConfiguration> is as follows:
defines the classes for managing and controlling the UIPAB.
defines the details of the views and their Controller.
defines the transitions of the navigation graph.
- Map the configuration file to the Controller
The view transitions are mapped to the Controller through node entries in the
<navigateTo navigateValue="next" view="View2" />
The Controller contains methods – developed by the developer - that invoke the UIPAB framework using the
navigateValue from the node elements. In the above example, the value of
navigateValue is “next”.
When View 1 is ready to transition to View 2, it invokes the
Next() method in the Controller:
SimpleController simpleController = (SimpleController)Controller;
The Controller navigates to the next view by calling the UIPAB framework and passing a string that corresponds to the
public void Next()
Note: The value of
navigateValue in the configuration file and the method name in the Controller are determined by the developer. In the above examples, “next” and “
Next()” were arbitrarily chosen. However, it’s a good idea to keep them in sync by using the same names with different type case.
Graphically, the process of transitioning to a View through the Controller and the UIPAB framework looks like the following:
The Navigation Graph and the Controller abstract the navigation and workflow logic from the views.
- Determine the starting view.
<navigationGraph> section contains an attribute that specifies the first view that uses the UIPAB
In Figure 8, the first view that uses the UIPAB is View 1. However, View 1 is not the initial view in the application. The initial view is the view that starts the UIPAB framework.
The initial view in the application doesn’t have to use the UIPAB block at all. For many applications, the initial view is a Login view for security purposes. When the user is authorized, the Login view starts the UIPAB framework by calling
UIPManager.StartNavigationTask("SimpleWinUIPAB"). This notifies the framework to display the view specified in
startView. Even though the Login View starts the framework it is not specified in the configuration file. This allows UIPAB and non-UIPAB code to be used together.
Note: The sample applications use “Start” as the initial view and “View1” as the value of startView. Web Applications still need to identify a start page to the .NET framework using “Set As Start Page”.
- Create the UIPAB Controller Class
Add a new class to the project for the Controller. Both Web and Desktop applications, inherit from
public class SimpleController : ControllerBase
Modify the constructor to accept a navigator object and call the base class constructor.
public SimpleController(Navigator nav) : base(nav)
Create the methods that correspond to the
navigateValues in the configuration file.
public void Next()
public void Previous()
- Compile and test.
A few extra comments are needed for the Wizard feature.
The SimpleWizardUIPAB sample contains an extra section in the configuration file called
<uipWizard> that defines the Wizard’s views. The views are ordered according to their linear sequence; View1 will transition to View2, etc.
Each View in the sample implements the
IWizardViewTransition interface in order to demonstrate custom behavior. It’s not necessary for the view to inherit from
IWizardViewTransition but it’s useful to do so to implement specific application behavior.
IWizardViewTransition provides the following methods for an application to implement:
DoNext(): Called prior to navigating to the next view.
DoBack(): Called prior to navigating to previous view.
DoCancel(): Cancels the wizard task.
DoFinish(): Called before finishing the wizard task.
SupportsCancel(): Indicates the particular wizard view supports the cancel behavior.
SupportsFinish(): Indicates the particular wizard view supports the finish behavior.
WizardActivated(): Called when a wizard view is activated.
For example, each view in the SimpleWizardUIPAB sample implements
SupportsCancel() to enable the Cancel button. If these methods were not implemented the Cancel button would be disabled by default.
The default behavior of the UIPAB framework is to disable the Cancel button.
The UIPAB framework automatically provides the buttons for Cancel, Back, Next Finish.
The UIPAB has many more features that are beyond this article. This article and its samples demonstrate the most basic functionality and much detail have been left out. Additionally, the entire framework can be configured to provide custom functionality. The samples, however, should provide a foundation to begin learning the UIPAB. After gaining an understanding of the samples, the Microsoft documentation and Quickstarts will make much more sense.
Note: included in the download is a short Hints and Tips document created during the development of the samples. Hopefully, it will save someone some grief.
Today’s software applications require an enterprise architecture that considers security, scalability, performance, reusability, and maintenance. Microsoft’s layered, service oriented architecture implemented with their Enterprise Library and the User Interface Application Block fulfills the needs of enterprise applications.
Additional reference links