Recently somebody asked me how a workflow could invoke another workflow that is loaded as XAML from a file or a database. This is a common request so I’ve added an activity to Microsoft.Activities to support this.
Update 2: 2011-09-26 The Sample has been updated to support loading of activity assemblies and setting the XamlXmlReader LocalAssembly
Download the Source for this example from MSDN Code Gallery – WF4 - How To Invoke a Child Workflow as XAML
Scenario: Load an Activity from a XAML Text File and Invoke It
- A child activity deployed as XAML text in a file which will run to completion when invoked (no bookmarks)
- A parent Workflow which needs to invoke the child activity that is not known until runtime
- The parent workflow is invoked
- It loads the child activity from XAML text
- and Invokes it passing arguments to the child activity
- and receives output from the child activity when it completes
Step 1: Construct an Example using an Early Bound (Compile Time) Workflow Dependency
For this simple example, I’ve create a child activity named Increment.xaml which accepts a number “Num” and increments it by one. This will be our child workflow.
The Parent Workflow is InvokeChild.xaml and it declares two variables StartingNumber (initialized to 3) and TheNumber which will be passed to the child workflow
For this working example, I’ve used the Increment activity and referenced it in the XAML at compile time. I want to have a good starting point for our example and as you can see it works.
Step 2: Add Microsoft.Activities to the project
In the latest release of Microsoft.Activities we have added several new activities to support this scenario
- LoadActivity – loads an activity from a XAML file
- InvokeWorkflow – Invokes an activity using WorkflowInvoker (no bookmarks supported)
- LoadAndInvokeWorkflow – Loads and Invokes using the other two activities
- DictionaryActivities – Invoking workflows requires you to create and manipulate dictionaries so we’ve added a set of Dictionary activities to support this
When I want to use Microsoft.Activities in a project I create a folder called Reference Assemblies, Download the latest release from http://wf.codeplex.com and add the assemblies to that folder. The I add a reference to Microsoft.Activities.dll.
Step 3: Change Increment.xaml to be treated as deployed content
Now I need to tell Visual Studio to treat Increment.xaml as content. To do this, in Solution Explorer, click on Increment.xaml and set the properties
- Build Action: Content
- Copy to Output Directory: Copy Always
- Custom Tool: (empty)
Step 4: Use the Microsoft.Activities.LoadAndInvokeWorkflow activity
Now I need to replace the Increment activity I added earlier with the LoadAndInvokeWorkflow activity. Sometimes Visual Studio doesn’t automatically add the activities from Microsoft.Activities to my toolbox. You can always add them manually if you need to.
- Delete the existing Increment activity
- Create a new Variable of type Dictionary<string, object> to hold the Input arguments named ChildArguments initialized to New Dictionary(Of String, Object)
- Create another new Variable of type IDictionary<string, object> named ChildResult
- Drop an AddToDictionary activity and set it to use types String, Object and set the properties
- Dictionary: ChildArguments
- Key: “Num”
- Value: TheNumber
- Drop a LoadAndInvokeWorkflow activity and set the properties
- Input: ChildArguments
- Path: “Increment.xaml”
- Result: ChildResult
- Drop an Assign activity and set the properties
- To: TheNumber
- Value: Convert.ToInt32(ChildResult("Num"))
Step 5: Test It
No surprise here – it works when you run it if you did all the steps correctly.
One note – if you were going to run the activity hundreds of times you should not use LoadAndInvokeWorkflow but instead use LoadActivity to load it once and then InvokeWorkflow to invoke it over and over again.