WF Scenarios Guidance: Workflow Designer Re-Hosting
Windows Workflow Foundation (WF or, Workflow) is Microsoft’s technology platform for building workflow-enabled applications. The platform includes a set of tools for designing and managing workflows, a programming model for implementing workflow logic, a rules engine, and a workflow runtime execution engine. Workflow technology can be employed in a wide range of application scenarios, the most common of which are listed in Table 1.
Table 1: Common production application scenarios for Workflow.
SharePoint 2007 relies on Workflow technology for its default workflows, and for custom workflows created with SharePoint Designer 2007 or Visual Studio 2008.
Workflow provides the underlying tools to support both human and system interaction according to business rules.
Seamless integration between Workflow and WCF enables workflows to be exposed as services and to coordinate calls to WCF services.
Both Windows and Web applications can leverage workflow to drive presentation flow.
Workflow Designer Re-Hosting
Applications can host the Workflow Designer to provide a fully customized design experience for developers or business users.
This whitepaper summarizes the value proposition for scenarios that involve re-hosting the Workflow Designer.
Workflow Designer Re-Hosting
Designer re-hosting refers to the ability to reuse the various controls offered within Visual Studio’s workflow design experience in custom applications outside of Visual Studio. The primary motivation for re-hosting is to provide a customized user experience for workflow design and tracking with greater control over the end-user experience. Such a tailored graphical interface enables non-developers such as business analysts to easily interact with workflows. These users are not likely to be familiar with the Visual Studio environment or need all of the features it offers. Re-hosting the workflow designer also provides a way to provide a branded developer experience for workflow, outside of Visual Studio. An extension of this is integrating aspects of the workflow designer into an existing application.
There are also technical requirements that influence the decision to re-host. Visual Studio may not be available or may not be an option for the intended users—for example, when the designer will be made publicly available across a large organization. Similarly, there might be a technical requirement for a lightweight deployment mechanism for the designer application so that it can be downloaded from a Web site or installed via ClickOnce.
Ultimately, workflow re-hosting capabilities translate to implementing workflow designer requirements without starting from scratch. Examples of specific applications that you might leverage re-hosting for include:
- Workflow Viewer: Providing a portable utility that can open any workflow definition and view it graphically.
- Workflow Instance Progress Map: Tracking the status of workflow instances graphically.
- Custom Workflow Designer: Supporting workflow design outside of the Visual Studio environment, possibly for non-developers.
The following sections will describe architectural features for workflow re-hosting, and then describe these implementation scenarios in greater detail.
Figure 1 illustrates the Workflow design components that can be re-hosted outside of the Visual Studio environment and used to create a compelling user experience for designing and interacting with workflows.
Figure 1: Components used in Workflow re-hosting scenarios.
These components provide the following functionality to a re-hosting scenario:
- WorkflowView: The WorkflowView control is generally referred to as the designer, particularly in the context of designer re-hosting. This feature-laden control is usually the core of any re-hosting scenario. Its primary function is to offer smooth navigation of workflow designs, providing drill-down capabilities necessary for composite workflow designs such as state machines. In addition, this control includes navigation features for panning and scrolling across wide or tall workflow designs as well as multiple zoom functions such as zooming to fit the window and incremental zooming. WorkflowView is also great for design scenarios since it supports drag and drop, and can be used to share designs visually through print, through print preview, and by exporting the displayed image to a file or stream. Rendering features of the WorkflowView control are also extensible so that developers can draw custom glyphs such as status icons.
- WorkflowOutline: Workflow designs can be wide and deep thus requiring a fair amount of scrolling, zooming, and drilling up and down to find the desired activity. The WorkflowOutline control provides a tree view summary of a workflow design and makes for very fast navigation to specific activities within the design.
- Toolbox: While the Toolbox itself is not a re-hostable control on its own, there is a well-defined service interface that integrates with WorkflowView and to support dragging activities from the Toolbox to the design surface, in addition to controlling the list of available activities.
- PropertyGrid: The PropertyGrid control is a standard Windows Forms control that can be used in many application scenarios. For Workflow re-hosting scenarios, this control is useful because it can engage the custom property editors and other actions used by Workflow activities. For example, this control can launch Workflow rules editors or be used to configure a dependency property.
Through the PropertyGrid control, the re-hosting scenario also has access to rule configuration dialogs (see Figure 2) so that the following functionality can be provided:
- Select Condition: This dialog lists defined rule conditions and supports adding, deleting, modifying, and renaming rules.
- Rule Condition Editor: This dialog lets users create and modify individual declarative rule conditions, with IntelliSense-like behavior that provides context-sensitive statement completion and syntax checking.
- Rule Set Editor: This dialog is used for configuring rule sets, including adding new rules and specifying their respective if conditions and then or else actions.
Figure 2: Workflow dialogs used in re-hosting scenarios.
From a high level, the architecture for a Workflow re-hosting scenario comprises a host process (usually a Windows client application built with Windows Forms or WPF), the integration of appropriate Workflow and Windows Forms components to enable functionality, and some application glue to provide desired user interaction and communication between components. Applications that re-host Workflow require the .NET Framework 3.0 at a minimum. If activities such as SendActivity and ReceiveActivity are to be used – applications that re-host Workflow require the .NET Framework 3.5, and the application must execute under FullTrust code access security. Figure 3 illustrates the components involved from this architectural view, and the sections that follow further describe how each component participates in the architecture.
Figure 3: Generalized architecture for a Workflow re-hosting application.
The WorkflowView control is the centerpiece of every re-hosting scenario. Developers can add this control to a Windows Form or WPF Window after wrapping it in a custom Windows Forms User Control (User Control) that exposes properties and events for application code to interact with. The WorkflowView control itself renders to a design surface within the User Control.
For the WorkflowView control to display a workflow design, it must first load the workflow definition. This is done through a custom derivation of the WorkflowDesignerLoader type. This type is responsible for loading and saving workflow definitions, and adding graphical components that describe the workflow to the WorkflowView. Developers typically implement a WorkflowDesignerLoader that loads and saves workflow definitions stored in XAML format, but it is also possible to generate assemblies that store workflow definitions. The former is the easiest option since the WorkflowMarkupSerializer can handle XAML serialization for the developer, while the latter requires additional coding to load and save definitions. Loading workflow definitions from an assembly involves specifying a workflow type or using reflection to inspect the workflow types it contains, and saving workflow definitions to a compiled assembly requires the use of the CodeDOM and the WorkflowCompiler class.
The WorkflowDesignerLoader is also responsible for initializing context menus, providing a cache of referenced components for the Toolbox, and exposing events for activity selection changes in the WorkflowView control. It accomplishes these things by registering the MenuCommandService, the TypeProvider, and the SelectionService, respectively. The MenuCommandService is used by the WorkflowView control to build the context menu that appears whenever a user right-clicks on its surface. With this service, developers can control what commands the designer can execute when right-clicking on an activity. The TypeProvider manages references to supporting types and effectively manages the collection of available assemblies with activities and other supporting business components. Its primary function is to act as a cache for the referenced components listed in the re-hosted toolbox. The user control that hosts the WorkflowView will register a handler with the registered SelectionService to expose an event that other controls in the application can handle when the currently selected activity changes.
Re-hosting scenarios also frequently leverage the WorkflowOutline control. Like the WorkflowView control, this control must be wrapped in a custom User Control before it can be added to a Windows Form or WPF Window. The WorkflowOutline control is connected to the WorkflowView control through an underlying SelectionService. This enables the WorkflowOutline control to implicitly use the workflow displayed in the designer as the root of its tree. In addition, whenever an activity is selected in the WorkflowView it is automatically selected in the WorkflowOutline and vice versa.
The PropertyGrid control is used to configure activities during workflow design. After adding the PropertyGrid control to a Windows Form or WPF Window, it must be connected to the WorkflowView in the re-hosting scenario to interact with the loaded workflow design. Once the two controls are connected, functions like displaying the Bind Dependency Dialog or expanding the rule condition property are available. To support the binding of activity properties to workflow properties or events to event handlers, a custom Event Binding Service must also be loaded into the WorkflowView. Finally, for complete control over how the properties are exposed in the property grid, it can be useful to implement a Property Value UI Service. This is required, for example, to display the database icon next to any property that can be bound with a Dependency Property.
By having the Property Grid in place with its supporting services, providing access to the rules dialog becomes effortless: users simply click on the [...] button next to the Condition Name property value of a declarative rule condition and the Rule Selection Dialog will appear, from which they can click Edit and the Rule Condition Editor will be displayed. The same logic applies to the Rule Set Editor that, for example, can be accessed via the RuleSetReference property of the Policy Activity.
The Toolbox is useful for building a custom workflow designer. It can be used to control the list of available activities and to support drag and drop between the Toolbox and the WorkflowView control in the re-hosting scenario. The Toolbox is created by hosting a custom User Control that implements the ToolboxService interface. This control must also be linked to the WorkflowView control, because it relies on the TypeProvider to gather references to the assemblies that contain available activities for the application.
Q. Can WorkflowView and WorkflowOutline controls be used directly in a custom application?
Although these controls are User Controls, they cannot be directly added to a Windows Form or WPF Window without first wrapping them in a custom User Control and explicitly defining properties and events for the application to interact with. Each application may have different requirements for how they interact with each control.
Q. In which client application platforms can I re-host the Workflow Designer?
Since the controls used in re-hosting scenarios are User Controls, they can in theory be employed wherever User Controls are supported. This includes Windows Forms applications as well as Windows Presentation Foundation (WPF) applications – where the latter requires an additional interoperability layer, the WindowFormsHost, which is the standard approach taken in WPF for re-hosting Windows Forms controls in a WPF Window. Internet Explorer can also host User Controls when the page being displayed contains the appropriate OBJECT tag – with the caveat that the application requires FullTrust. In addition, there is limited support for cross-browser applications by way of using the WorkflowView control to generate bitmap snapshots of the workflow it is rendering, and stream it to the browser. This technique can be used to create a graphical progress map viewable from within any browser.
Silverlight applications lack the ability to re-host Windows Forms Controls, and therefore cannot currently re-host Workflow controls.
Q. Does re-hosting always require FullTrust?
Any environment that re-hosts the Workflow designer controls must be granted FullTrust code access security. Applications copied to the local machine are usually granted FullTrust; applications deployed with ClickOnce can require FullTrust; and .NET code running in the IE hosting environment can be granted FullTrust if the default security policy is adjusted. By default, IE-hosted code is not granted FullTrust.
Capturing complex business processes in workflow definitions provides a model for the workflow runtime to execute, but the graphical representation of the definition is also key to validating that the business process is accurate, modifying aspects of the process if necessary, and monitoring the status of running processes. Developers must be able to visualize workflows not only during development, but after they are deployed. Business users must be able to visualize workflows to validate their accuracy and comment, or to monitor the status of running processes. Outside of Visual Studio there isn’t a tool to view workflow definitions – however using re-hosting techniques it is possible to build a portable utility that can open any workflow definition and view it graphically. This type of utility can be used to view XAML-based or assembly-based workflows – the latter of which even Visual Studio cannot view unless the full source code is available. A custom workflow visualize also has the potential advantage of being a lightweight, easy to deploy application.
Figure 4 illustrates a simple example of an application that enables users to view workflow definitions. The implementation characteristics of this application using re-hosting techniques will be discussed in the following sections.
Figure 4: A simple example of a workflow definition visualizer.
A workflow visualizer application will typically provide users with the following functionality:
- The ability to view workflow definitions defined in XAML files or assemblies. Although the runtime format for a workflow definition is consistent regardless of the storage format, the code to load a workflow definition into that format must be provided by the developer.
- The ability to navigate composite activities by drilling up and down the hierarchy. The WorkflowView component provides this functionality once it is initialized with a workflow definition.
- Context menus to control zooming, panning, and printing. The WorkflowView component also provides this functionality for the loaded workflow definition.
The implementation architecture for a simple workflow visualizer is illustrated in Figure 5.
Figure 5: Implementation architecture and components that contribute to a simple workflow visualizer.
This architecture is a distillation of the re-hosting architecture previously introduced. As Figure 5 illustrates, the application is a Windows application that relies on the WorkflowView control for its core functionality. At a minimum, the application must provide a way for the user to navigate the file system and load workflow definitions, and the code necessary to initialize the WorkflowView with the selected definition. If the workflow definition is stored in an assembly, the user will select a particular workflow type from within that assembly; thus, a dialog must be presented to enable users to navigate the available workflow definitions within an assembly. If the workflow definition is stored in a XAML file, the user can simply select the file for view.
The process for loading a workflow definition for the WorkflowView control to display differs slightly based on the source of the definition. For a XAML-based workflow, the XAML file must be deserialized to an instance of Activity, which is done via the WorkflowMarkupSerializer. Once the Activity tree is available, the custom implementation of the WorkflowDesignerLoader is responsible for navigating the tree and adding each of its activity components to the design surface that encapsulates the WorkflowView. For workflows loaded from an assembly, the WorkflowMarkupSerializer is not necessary because the Activity tree is immediately available from instantiating a new instance of the workflow type.
Q. How does loading workflow definitions into a WorkflowView from XAML compare to loading them from an assembly?
Ultimately, the WorkflowView component renders a workflow definition from an Activity type instance. To load a workflow definition from a XAML file, developers implement logic to enable the WorkflowMarkupSerializer, which deserializes a XAML stream into an Activity instance. To load a workflow definition stored in an assembly, this serialization logic is not necessary. Instead, an instance of the Activity type stored in the assembly can be directly instantiated. In either case, once an instance of an Activity that represents a workflow is available, it can be added to the WorkflowView for rendering.
Q. How can the correct workflow definition for the WorkflowView be found in an assembly?
Many applications may know the workflow type in advance and directly load this type from the assembly. In more dynamic situations, reflection can be used to find all types that derive from SequentialWorkflowActivity or StateMachineWorkflowActivity. In this case, a list would be presented to the user to select from.
Graphical Progress Monitor
Applications that rely on workflow to coordinate complex business processes typically comprise one or more client applications enabling business users to initialize workflows and otherwise interact with running instances of those workflows. Different users may interact with different application interfaces to control how users can advance workflow state or complete a workflow. As workflows execute, it can be helpful to provide an interface to visualize the active progress of a running workflow instance based on the workflow definition. This feature can be an integral part of a workflow-driven application, or useful to application administrators monitoring all running workflows and their status.
Using the WorkflowView control, a graphical progress monitor can be created to support rich exploration of workflow instances and superimpose relevant status details for each activity in the workflow. Status indicators can be application-specific so that business users can easily relate them to their business domain. The visual representation of the workflow instance and its status can also be saved to a file, printed, or sent via e-mail to other business users.
Figure 6 illustrates a simple application that provides this type of workflow progress monitor. The sections to follow will describe the implementation characteristics for this type of application.
Figure 6: A simple example of a workflow instance progress monitor.
A workflow progress monitor application will typically provide users with the following functionality:
- The ability to select from a list of running workflow instances, and choose one for which status should be displayed. Examples of status for each activity include Not Executed, Executing, Canceling, Closed, Compensating, or Faulted. This requires access to the information stored by the Workflow Tracking Service, which records the status or running workflows as states are traversed. The application could expose this information through a WCF service with operations to return a list of running workflows, and to return state information specific to a particular workflow instance.
- The ability to view state information for a particular workflow instance. The WorkflowView component provides this functionality with the addition of a custom glyph provider and custom glyphs to represent activity state.
- Context menus to control zooming, panning, and printing—functionality the WorkflowView provides—in addition to any custom actions relevant to viewing workflow progress. For example, users can save the progress map to a file, send it via e-mail, or print it.
As with the workflow visualizer discussed previously, the application would also provide core functionality to load workflows from XAML files or assemblies, and to navigate the hierarchy of a workflow definition.
Figure 7 illustrates the logical architecture of the graphical progress monitor.
Figure 7: Implementation architecture and components that contribute to a simple progress monitor application.
This architecture builds upon the architecture described for a workflow visualizer application in that it also relies on the WorkflowView component to provide the majority of the functionality, and an implementation of the WorkflowDesignerLoader to initialize the WorkflowView with a workflow instance. These additional features for the progress monitor application are represented in Figure 7:
- The WorkflowView not only is initialized with a workflow definition, but it also displays workflow status information through one or more GlyphProvider instances associated with the WorkflowView.
- The Workflow Tracking Service is enabled to track running workflows and store information about their current status in the tracking database.
- A custom WCF service enables the client application to gather information from the tracking database, including a list of running or active workflows and information about each workflow’s status.
The key element to implementing a progress monitor is the ability to render graphical information related to workflow instance status on top of the workflow definition displayed by the WorkflowView component. This is done by adding a custom DesignerGlyphProvider to the WorkflowView instance. In typography parlance, a glyph is just a letter or a symbol, and in Workflow a glyph provider implements logic to determine what glyphs should be drawn as adornments to a specific activity. There can be multiple glyph providers loaded, each responsible for deciding when to paint a different glyph. Ultimately, all glyph providers are registered with the DesignerGlyphProvider Service prior to the WorkflowView rendering its display. Figure 7 illustrates a single glyph provider associated with a WorkflowView instance, and many glyphs associated with the provider. The glyph provider knows how to draw the correct glyph for each possible activity state: for example, a blue checkmark for a closed activity (shown in Figure 6) or a green play icon for an executing activity.
For the glyph provider to know the correct state for each activity, the Workflow Tracking Service must be employed to gather this information as workflows execute. Since tracking is a feature of Workflow, this does not require much effort; however, to expose this information to the application, additional steps are required. Figure 7 illustrates a WCF service exposing information about running workflow instances, and information about the state of each workflow. This information is typically returned as custom types specific to the application. To request state information for a particular workflow instance, the workflow instance identifier is passed to the WCF service. State information is associated with the glyph provider. When the WorkflowView asks the glyph provider for the glyphs to draw on an Activity, the provider can interrogate this state information to determine the appropriate Glyph to render.
The graphical progress monitor application is not likely to be deployed to the same machines as are running workflow instances. This presents a challenge related to assembly dependencies between client and server applications. When the WorkflowView component is initialized with a workflow definition, the definition can be stored in a XAML file or in a compiled assembly. Ultimately, both workflow definitions will have dependencies on other .NET assemblies or custom assemblies for Activity types employed by the workflow. The progress monitor must then have access to any relevant XAML or assembly files necessary to render the workflow definition, and this may require access to multiple versions of XAML files and related assemblies as workflow definitions evolve over the lifetime of the application. In other words, the WorkflowView component must be able to load the correct assembly dependencies for different versions of a workflow definition from the client machine. There may be running workflow instances to be rendered that are based on different versions of a workflow definition.
This creates a need to deploy the required XAML and assembly files to the client machine. Dependencies that belong to the WorkflowRuntime are likely to be deployed with the appropriate version of the .NET Framework being used by the application. At a minimum, the .NET Framework 3.0 will be deployed to client machines in order to support Workflow. The .NET Framework 3.5 must be deployed if new activities such as SendActivity and ReceiveActivity are employed. Subsequent releases may add additional dependencies.
As for application-specific XAML and assembly dependencies, the client application can deploy all required files during initial installation and provide updates those files as needed using ClickOnce technology. This works well when the number of workflow definitions and related dependencies are reasonably small and change infrequently. Figure 8 illustrates the logical flow for initializing the WorkflowView control when required assemblies are deployed to the client machine.
Figure8: Logical flow for pre-installing workflow dependencies to the client.
In the case where there are too many XAML and assembly files to deploy in advance, another possible solution is for the application to download the required files from a Web server, on demand. ClickOnce technology can also be used to perform partial deployment and on-demand updates for the application. Figure 9 illustrates the logical flow for an on-demand deployment scenario where the server application holds the assemblies required by the client progress monitor.
Figure 9: Logical flow for downloading workflow dependencies on demand for the client.
Q. How can I render workflow state according to different business rules?
An application can use multiple glyph providers when the rules for rendering glyphs for a workflow instance differ. For example, in this scenario only activity status is considered, so only activity status glyphs are drawn. The logic which examines activity state and determines the appropriate status glyph to render is best encapsulated in a single glyph provider. If other business needs dictate that additional graphical information should be rendered based on different rules, these would be encapsulated in a different glyph provider—for example, if you wanted to overlay a time-stamp on the activity that shows when the activity was completed.
Custom Workflow Designer
Custom workflow visualizers or graphical progress monitors like those discussed in the previous sections are usually designed to be part of an end-user application and are not part of the workflow design phase. If there is a requirement to enable business analysts to participate in workflow design, a more complex re-hosting scenario is required. For business analysts, you need to offer a designer that is much less complicated than Visual Studio, and a user experience that is intuitive and does not require writing code.
This can be achieved using the full suite of Workflow re-hosting components discussed earlier, including WorkflowView, WorkflowOutline, Toolbox, and PropertyGrid. PropertyGrid also provides access to relevant Workflow dialogs or custom dialogs for configuring activities. To facilitate an intuitive user experience close to their business domain, custom activities relevant to the business domain can be created in advance to populate the Toolbox with a more coarse set of activities that encapsulate the custom code required to execute related system functionality.
Figure 10 illustrates a possible implementation for a custom workflow designer. The following section will elaborate briefly on its implementation characteristics.
Figure 10: A simple example of a custom workflow designer.
Like the workflow visualizer re-hosting scenario discussed earlier, a custom workflow designer application will also include functionality to load workflows from XAML files or assemblies and view them in the WorkflowView component; the ability to navigate a workflow definition hierarchy; and context menus for features such as saving or printing workflow designs. Most of this functionality is provided by the WorkflowView component.
A custom workflow designer will typically extend this functionality by providing the following features:
- The ability to not only read workflow definitions, but also to write to them as XAML files or assemblies. If the application targets business users, XAML will be the preferred format since no code will be generated for these workflow definitions.
- Custom activities that encapsulate logic for the business domain. Developers design these activities in advance to support the business user, and compile them into assemblies for distribution as part of the workflow designer application.
- A Toolbox populated with a limited set of workflow activities and any relevant custom activities to the application.
- The ability to drag and drop activities from the Toolbox to the design surface hosting the WorkflowView component.
- Access to the PropertyGrid to set properties for all activities including custom activities, and access to rule configuration dialogs provided by Workflow, or custom dialogs through extensibility.
The implementation of a custom workflow designer shown in Figure 11 very closely mirrors the general architecture introduced earlier.
Figure 11: Implementation architecture and components contributing to a custom workflow designer.
As with earlier examples, the client application hosting each of the Workflow components can be a Windows Forms or WPF application. To create a complete workflow design experience like that offered by Visual Studio, the application will leverage all of the controls discussed for re-hosting, including WorkflowView, WorkflowOutline, PropertyGrid, and the Toolbox. The connections between these controls are as discussed earlier. As with the workflow visualizer scenario, this scenario primarily relies on the WorkflowView control to load and display workflow definitions, and to control context menu options available to users as they interact with the design surface.
This scenario also depends on the WorkflowView control to save new workflow definitions. Although it is possible to save workflow definitions as XAML files or as assemblies, it is likely only to be the former for business users since they will not be writing code to accompany the workflow definition they generate using custom activities. When the user wants to save a workflow definition, the WorkflowDesignerLoader handles saving the activity tree associated with the WorkflowView control to XAML using the WorkflowMarkupSerializer to handle serialization. If any rules have been defined through the PropertyGrid, a rules file must also be saved for the definition. For state machine workflows, the layout must also be saved.
Q. Can design-time features like activity validators, designers, Toolbox items, and property editors be used in a re-hosting scenario?
Yes, though they individually depend on the hosting application for a certain amount of support. For example, validators add value because they can display warnings and errors in Visual Studio's Error List tool window. In a re-hosting scenario, the application must provide this window if the default behavior of the designer does not suffice.
Q. Which offers greater customization options—designer re-hosting or customizing the Visual Studio Shell?
Both offer a similar degree of customizability with regards to Workflow components. The Visual Studio Shell extensibility differs in that it provides the supporting infrastructure for projects, windows, menus, and document handling.