Runtime modification of workflow's
Modifying already executing workflow's is a very powerful option. Now, as with most advanced options, not something you are going to need every day but certainly something to be aware of and use when the needed.
First lets take a quick look at why we would want to modify an already running workflow in the first place.
Consider the following scenario. You have long running, lets assume a year on average, and part of the workflow has to do with shipping products. And lets assume that the shipping is done by any one of a number op shippers and that this involves multiple steps, sort of a mini workflow itself, which are different for each shipper. Now you could add a big IfElseActivity with a branch for each possible shipper and be done with it. But now suppose the company starts doing business with a new shipper. So you go and add an branch to the IfElseActivity and implement the new shipper, no big deal. But all already running workflow's are based upon the original workflow without the new shipper, so they cannot use the new shipper. And if the new shipper is a lot cheaper that means you have to explain why all the additional shipping costs are made :-(
So how to solve a problem like this?
Well is we decide to add the shipping activity to the workflow at runtime, at the moment we actually need it, we get the flexibility we need. In fact it even makes the workflow simpler as we don't need to implement the big IfElseActivity. And in software development simple is good :-)
So what do we actually need to change an executing WorkflowInstance? The class to start with is the WorkflowChanges. This WorkflowChanges object has a property named TransientWorkflow that lets us get to the actual workflow definition. Now we can use this to add the activities we want. In fact we can also change or remove activities as well.
One easy way is to add a SequenceActivity as a placeholder where you want to add your new functionality like this:
Adding an extra activity is done from codeActivity3 (actually the second in the workflow) with the following code:
WorkflowChanges changes = new WorkflowChanges(this);
SequenceActivity activity =
NewActivity newActivity = new NewActivity();
newActivity.TextToPrint = "This is a dynamically added activity!";
ValidationErrorCollection validationErrors = changes.Validate();
catch (WorkflowValidationFailedException ex)
validationErrors = ex.Errors;
foreach (var error in validationErrors)
The most important thing to notice is that the ApplyWorkflowChanges is the one that actually changes the running WorkflowInstance. And if the update fails for some reason an WorkflowValidationFailedException is thrown with a property Errors that is a collection of ValidationError objects.
Before using the ApplyWorkflowChanges function we van validate the changes. This will catch some, but not all possible, errors so just validating and removing the try/catch is not recommended.