Workflow Foundation (WF4) – Rehosting The Workflow Designer
Rehosting the WF designer in an application outside of Visual Studio is nothing new and since WF4, nothing particularly difficult. In fact the WF product team has gone out of its way to make rehosting the designer as easy an experience as possible and they’ve done a great job. The WCF and WF Samples for .NET Framework 4 provides code samples for rehosting the designer with its corresponding toolbox and properties grid. The samples also cover handling validation errors, executing workflows and providing some level of debugging through workflow tracking – most of what you need to write your own rehosted designer.
But to get a useable app you’re going to have to write some boiler plate code to stitch all these concepts together. You’ll need code to open, save and execute workflows. You’ll need to manage window layout, display workflow output and handle runtime exceptions. And wouldn't it be nice to support working with multiple workflows at the same time all in a windowing environment that supports docking and pinning?
Enter Workflow Studio– a simple, generic application that allows you to design and execute multiple XAML based workflows in a windowed environment akin with Visual Studio. Use it to design and test your workflows in environments where Visual Studio is not the right tool. You can even use it as a simple hosting environment. I’ve developed Workflow Studio as an application you can use out of the box, or you can use it as the basis for your own specialised implementation. You can download the source code here.
Features
The following image shows the Workflow Studio environment:
Here’s a rundown of its features and where appropriate I've provided references to sample code should you want to understand more about the implementation detail.
- Develop XAML Based Workflows And Workflow Services
Use the fully fledged WF designer to develop XAML based workflows and workflow services just as you would in Visual Studio. Interaction between the toolbox and properties box is just as in Visual Studio. For workflow services, add any WCF configuration to the Workflow Studio app config file. The solution comes with a test workflow service and client with appropriate configuration in the app config file as an example. Look at the Designer Rehosting example in WCF and WF Samples for .NET Framework 4 that demonstrates the basis for this implementation. Also, Pro WF Windows Workflow in .NET 4 by Bruce Bukovics has a great chapter on designer rehosting. Should you wish to execute other XAML based child workflows from a workflow then you can use the ExecuteXamlWorkflow custom activity I described in my previous post. - Work On More Than One Workflow At The Same Time
Workflow Studio allows you to develop multiple workflows in a single application. - Toolbox Support For All Standard WF Activities
All standard WF 4.0 activities are supported. - Add Custom Activities To The Toolbox
To add custom activities to the toolbox, copy the custom activity DLL to the bin folder of Workflow Studio, select the "Add Reference …" option and locate the DLL file. The custom activity will then become available in the toolbox. If your workflow references custom activities then these will be automatically loaded and added to the toolbox when the workflow is loaded providing the referenced DLL has been previously copied to the bin folder. The section on designer rehosting in Pro WF Windows Workflow in .NET 4 by Bruce Bukovics, providing the details of toolbox manipulation that I used as basis for Workflow Studio. - Execute Workflows Concurrently
You can execute one or more workflows or workflow services concurrently by either selecting "Start Debugging" or "Start Without Debugging" from the debug menu. Running workflows can be stopped by selecting "Abort" from the same menu. Each workflow has its own independent output window where WriteLine activity or exception stack trace output is written. You can also capture output through a trace source and associate a listener to log the output. We're using standard .NET diagnostics here, so it's totally flexible. - Show Workflow Validation Errors
Any validation errors detected by the designer are displayed in the error window along with error code and severity. Each workflow has its own independent window. - Debug Workflows
This isn't fully fledged Visual Studio debugging - it's workflow tracking. You'll see the currently executing activity highlighted in the designer so you'll be able to visually track the execution path of your workflow in real time. As each activity executes the activity name, id, state and workflow instance id are written to the workflow's debug window. Clicking on a row in the debug window will focus the designer on the corresponding activity. Similar to workflow output, the debug window output is also captured through a trace source so that output can be logged. Check out Visual Workflow Tracking in WCF and WF Samples for .NET Framework 4 which demonstrates how to implement visual tracking in the designer. - Visual Studio Like Window Docking And Pinning
One of the key features of Workflow Studio is to offer full window docking and pinning functionality that you find in Visual Studio. This functionality is provided by the AvalonDock open source WPF docking framework. This is a great framework but took some jumping through hoops to get working. I started out wanting to make this a pure MVVM application but soon discovered this wasn't easy, if at all possible. Apparently this is addressed with the up and coming 2.0 release along with other improvements. Note that you'll need to download and install AvalonDock independently of Workflow Studio since I don't redistribute it here - don't worry this is simple. Unfortunately there's no NuGet package available as yet so please follow instructions below.
Other Features
Persistence
Persistence for Workflows other than workflow services is not currently supported. Workflows are hosted using the WorkflowApplication class and persistence makes little sense unless you can implement code that interacts with the host to load and unload instances and this is not possible with Workflow Studio currently.
On the other hand, persistence for Workflow services is supported. Here, interaction with the host is not required since persistence is triggered through service interaction. Workflow services are hosted using the WorkflowServiceHost class and this allows all persistence behaviour to be configured in the app config file. I used Leon Welicki's great post on long running workflows with WCF to see how this would work and whether the debugging mode could help trace workflow execution. Here's how it looked:
Sending the debug output to a file (see below) really comes into its own here as you can sort and filter the output in an application such as Excel to look at the execution sequence of individual workflow instances.
Localization
Workflow studio is easily localizable. All text strings are defined in the resources.resx file that can be found in the solution properties folder. Simply translate this to your required language and rename using the naming convention for resource files. Resources are selected according to your current locale, so if you need the ability to select locales other than your current one you will need to implement this feature yourself.
Output Logging
As mentioned previously, all workflow output and debug tracking output is captured using trace sources that can be associated with listeners that log output. Output can be captured either per workflow or collectively.
Here's an example from the supplied app config file:
1: <!-- for output, add new sources here where name must match workflow name without file extension, suffixed with "Output" -->
2: <source name="TestLoopWithDelayOutput"
3: switchType="System.Diagnostics.SourceSwitch"
4: switchName="verboseSwitch">
5: <listeners>
6: <add name="testLoopWithDelayOutputListener"
7: type="System.Diagnostics.TextWriterTraceListener"
8: initializeData="TestLoopWithDelayOutput.log">
9: </add>
10: <remove name="Default"/>
11: </listeners>
12: </source>
In the above example, the workflow document tab with the name "TestLoopWithDelay.xaml" will write its output to the file TestLoopWithDelayOutput.log. The source name must match the workflow document name, excluding the extension and suffixed with “Output”.
Each workflow will also write its output to a single shared output file, so you don’t have to configure the above if your don’t require the output in a separate file:
1: <!-- The AllOutput source captures output for all workflows -->
2: <source name="AllOutput"
3: switchType="System.Diagnostics.SourceSwitch"
4: switchName="verboseSwitch">
5: <listeners>
6: <add name="allOutputListener"
7: type="System.Diagnostics.TextWriterTraceListener"
8: initializeData="AllOutput.log">
9: </add>
10: <remove name="Default"/>
11: </listeners>
12: </source>
A trace source is also associated with exception handling. In the same config section you'll notice that a listener logs all exceptions to the Error.log file of the bin folder.
Similar to workflow output, debug tracking output is captured using trace sources and each workflow can have it’s tracking captured independently or collectively. Where specifying the trace source for debug tracking the source name must match the workflow document name, excluding the extension and suffixed with “Debug”. Collective output is written to “AllDebug.csv”. The configuration uses the System.Diagnostics.DelimitedListTraceListener that writes output to a comma delimited file. This is ideal for loading into say Excel, where you can filter and sort to see the execution path of a specific workflow instance.
Controlling Debug Output
The following settings in the Workflow Studio app config file allow you to control the tracking output behaviour:
PauseBetweenDebugStepsInMilliseconds | The number of milliseconds to pause before moving onto the next activity. This allows you to see the execution path more easily as the workflow executes in real time. |
DisableDebugViewOutput | You may only be interested in tracking output sent to a file in which case you can disable interactive tracking by setting this value to true. |
Installing AvalonDock
As previously mentioned, AvalonDock is not distributed with Workflow Studio so you need to download and install it first. This version of Workflow Studio has been developed with version 1.3.3571 of AvalonDock so please ensure you install this version. The steps are simple:
- Download AvalonDock version 1.3.3571 from https://avalondock.codeplex.com/releases/48794/download/131885
- Run the installer. This will GAC the AvalonDock assembly.
- Build the solution. You should not need to modify any references.
Conclusion
Hopefully you’ll find Workflow Studio a useful application for designing and debugging workflows in environments where Visual Studio is not a viable option. You can even use it for simple workflow hosting. It’ll save you writing a lot of boiler plate code and can serve as a starting point for your own implementation should you require something more specialized. I’d be interested to hear if you find Workflow Studio useful and welcome any feedback for possible enhancements. Also, please let me know of any bugs you may find.
Workflow Studio has been updated for .NET 4.5 to take advantage of some of the new designer improvements. If you are using .NET 4.5 and Visual Studio 2012 then it is recommended you use the version described in this post.
Written by Christopher Owczarek
Comments
Anonymous
April 16, 2012
Dear Christopher Owczarek, Your artical is brilliant but the code is broken. I downloaded the zip file here(code.msdn.microsoft.com/Workflow-Studio-df1d7dc0) and tried many times. But I could not unzip the file because it is broken. May you fix it? Thanks lot. Wenhao SHEAnonymous
April 17, 2012
I found a tool to repair the zip file and now it is working. Where I could find some manual or tutorial for your project?Anonymous
April 24, 2012
Hi Shewenhao, The download link seems to be working fine now - not sure what the problem was. Regarding a tutorial, please refer to the "WCF and WF Samples For .NET framework 4" documentation on which this application is based (see msdn.microsoft.com/.../dd483375.aspx). Thanks Chris.Anonymous
April 24, 2012
This is exactly what I was looking for. Are there any licensing restrictions or can this or pieces of this be used in commercial application?Anonymous
April 27, 2012
Dear Christopher Owczarek, It works like a charm now. Thanks!!Anonymous
May 07, 2012
Steve, yes it can be used in a commercial application providing you adhere to the Apache license (for Workflow Studio) and new BSD license (for AvalonDock).Anonymous
May 21, 2012
Hi, what is the URL ro download the Worflow Studio please? ThanksAnonymous
May 21, 2012
Go to code.msdn.microsoft.com/Workflow-Studio-df1d7dc0Anonymous
May 30, 2012
In order to run and use Workflow Studio do I need to have Visual Studio 2010 installed on my machine? First I was under the impression that Workflow Studio does not need VS2010 to be present on the same machine, but when I went to the download site, it mentions vs2010 as a requirement. I would highly appreciate your clarification. Thanks.Anonymous
June 15, 2012
You do not require Visual Studio 2010. The only prerequisite is you install .NET 4 Framework and AvalonDock version 1.3.3571 from avalondock.codeplex.com/.../131885.Anonymous
June 15, 2012
I'll just clarify that last point. You need VS 2010 to download and build the application since I have not posted the binaries. However users of the application do not require VS 2010 installed. Thanks.Anonymous
June 20, 2012
Hi Christopher, Greater sample... I am finding an issue where actvities are missing from the toolbox. for example, I noticed in the code that 3 actvities are supposed to be shown under flowchart - typeof(Flowchart), typeof(FlowDecision), typeof(FlowSwitch<> but at runtime only flowchart shows in the toolbox. I also noticed that this seems the case in the screenshots in the blog (it only shows one activity which is Flowchart) any thoughts as to the cause and remedy?Anonymous
June 20, 2012
I think I have figured out the issue. Had to change IsValidToolboxActivity to allow for generic params (I noticed ForEach, AddtoCollection etc etc was not included either and also to allow for activiies from FlowNode). My new method below. private bool IsValidToolboxActivity(Type activityType) { return activityType.IsPublic && !activityType.IsNested && !activityType.IsAbstract && (typeof(Activity).IsAssignableFrom(activityType) || typeof(IActivityTemplateFactory).IsAssignableFrom(activityType) || typeof(FlowNode).IsAssignableFrom(activityType)); }Anonymous
July 01, 2012
Pierre, Thanks for bringing this bug to my attention. Your solution looks like the correct fix. I'll be applying this in the next version.Anonymous
July 16, 2012
Hello Christopher, I realized that a new AvalonDick Version 2.0 has been released (avalondock.codeplex.com/wikipage). It fixes a lot of issues, but it is completely incompatible with Version 1.x. Do you plan to migrate this example to AvalonDock Version 2.0? Thank you in advance for any help! Greetings - RichieAnonymous
August 02, 2012
The comment has been removedAnonymous
October 19, 2012
Hi Styrna, The reason for this is because you have not defined your service endpoint in the configuration file. When you add a new workflow service you must also provide corresponding WCF configuration in the Workflow Studio app config file - this app will not do that for you. If you look in the app config file you will see an example of this for the TestService.xamlx example that you can find in the TestWorkflow folder. It looks like this: <services> <service name="TestService"> <host> <baseAddresses> <add baseAddress="http://localhost:9000/"></add> </baseAddresses> </host> <endpoint contract="IService" address="http://localhost:9000/service" binding="wsHttpBinding"></endpoint> </service> </services> You can either reuse this if the definition matches your requirements or define your own. The key thing is that the service name matches the "ConfigurationName" property that you see in the property grid (seen when you click the workflow service activity in the designer). In your example, you have used the default "Service1".Anonymous
October 19, 2012
Richie - no plans to migrate to AvalonDock v2 just yet - this would require a fair bit of work. However I do intend to upgrade Workflow Studio to .NET 4.5 and take advantage of some of the new Workflow designer features so stay tuned ...Anonymous
November 06, 2012
hi, i can get it to work: it compiles and run but any time i write a VB expression it crashes (something times out and tries to compile i think). How can i fix this any idea?Anonymous
October 21, 2013
Great work! I recently ran into problems with German Umlauts (ü,ä..) and had to change ASCIIEncoding from Default to UTF8 in WorkflowHostRunner.cs and WorkflowRunner.cs. OLD: MemoryStream ms = new MemoryStream(ASCIIEncoding.Default.GetBytes(this.workflowDesigner.Text)); NEW: MemoryStream ms = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(this.workflowDesigner.Text));