Workflow Reflection Utility Sample

Download sample

The Workflow Reflection Utility is an extensible tool for extracting workflow-related information from an assembly. Each workflow's hierarchy, declarative rules, and required local services are displayed in a tree view. This allows for easy browsing of the compiled workflow's structure. Additionally, each workflow in the assembly can be viewed as XAML in Notepad or on a rehosted designer surface. Finally, a substitution-based declarative rule evaluator provides the user a way to do "what if" analysis of contained expressions.

Using the Sample

Follow these steps to build, run, and configure the sample.

To build the sample

  1. Download the sample by clicking Download Sample in this topic.

    This extracts the sample project to your local hard disk.

  2. Click Start, point to Programs, point to Microsoft Windows SDK, and then click CMD Shell.

  3. Go to the source directory of the sample.

  4. At the command prompt, type MSBUILD <Solution file name>.

To run the sample

  1. In the SDK Command Prompt window, run the .exe file in the WorkflowReflectionUtility\bin\debug folder, which is located below the main folder for the sample.

To load an assembly into the Workflow Reflection Utility:

  1. Start the WorkflowReflectionUtility.exe program.

  2. On the File menu, select Open.

  3. Select the assembly that contains the workflow content that you want to explore and then click Open.

  4. When the assembly is loaded, browse through the tree view by expanding the nodes.

    Some nodes have context-sensitive menus. One example is the WorkflowNode, which supports viewing the XAML in Notepad or viewing the workflow on a rehosted design surface.

Configuration File

The Workflow Reflection Utility is controlled by an application configuration file. This file contains a WorkflowReflectionUtilitySection, which adds one or more ReflectionComponent objects to the components collection. If the configuration file is missing, the utility falls back on a hard-coded, programmatic version of the default configuration file.

By default, the Workflow Reflection Utility is configured to display all the workflows that are contained in the assembly. For each workflow, it shows all declarative rules, all DataExchangeService interfaces used, and the activity hierarchy. The substitution-based rule expression evaluator can be accessed through the right-click shortcut menu for declarative rule tree nodes. You can access the XAML and designer views by using the right-click shortcut menu for workflow tree nodes.

Default Configuration

The default configuration is as follows:

        <section name="WorkflowReflectionUtilitySettings" type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.WorkflowReflectionUtilitySection, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
    <WorkflowReflectionUtilitySettings showAssemblyResolveExplanation="true">
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.AssemblyComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.WorkflowComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.RuleComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.XomlContextMenuComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.RequiredServiceInterfacesComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.RuleEvaluatorComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.WorkflowDesignerViewComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>
            <add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.WorkflowActivitiesComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>


The Workflow Reflection Utility was designed for extensibility. To add more functionality to the tool, you must add a new component that is derived from WorkflowReflectionComponent that contains two abstract methods:

public abstract void Initialize(InitializationContext context);
public abstract void PerformReflection(ReflectionContext context);

Initialize Method

The Initialize method is called when the utility starts. It enables the component to configure itself to run at reflection time. InitializationContext.AddChild is used to add the current component as a child of some existing component type. After initialization, calls to this method build a tree structure of components that represents the steps that are taken to perform reflection on the assembly. For example, the AssemblyComponent adds itself as a child of the RootComponent, and the WorkflowComponent adds itself as a child of the AssemblyComponent. This creates the following call structure at reflection time: Root > Assembly > Workflow. There is no limit to the number of children that a component can have. There is also no limit to the number of parents that a particular child component can add itself to.

InitializationContext.AddImage is used to add an image to the list of those that can be displayed in the tree view. Each image is cached based on owner type and a string name. These two values are used as keys to retrieve the ImageList index for the image at reflection time.

PerformReflection Method

The PerformReflection method is used to do the actual work when an assembly is loaded. The ReflectionContext provides the component with accessors for the assembly, the current tree node, and the whole tree view. Additionally, the ReflectionContext provides methods for getting all child components, getting previously cached image indexes, and creating a cloned context.

As an example, we can explore the RuleComponent. The RuleComponent adds itself as a child of the WorkflowComponent and adds a cached image at initialize time. At reflection time, the component accesses the current tree node (which is a WorkflowNode) to get the workflow type. It then reflects on this type to find all the declarative rules and to add nodes for each of these. For each node that it adds, it calls the WorkflowReflectionComponent.InvokeChildComponents method with a cloned ReflectionContext that contains the newly added rule node.

This general pattern can be used to add context menus to nodes, change the text of nodes, reorganize nodes, and add child nodes. For samples and more information, see the OutOfBoxComponents.cs file.

Configuring the New Component

New components must be added to the configuration file to run. For the full structure of the configuration file, see the "Configuration File" section in this topic.

The new component node looks like the following:

<add type="[AssemblyQualifiedName of component]"/>

For example:

<add type="Microsoft.Samples.Workflow.Applications.WorkflowReflectionUtility.AssemblyComponent, WorkflowReflectionUtility, Version=, Culture=neutral, PublicKeyToken=null"/>

See Also

Other Resources

Application Samples
Windows Workflow Foundation Samples

© 2007 Microsoft Corporation. All rights reserved.