Workflow Designs Can Vanish
After coming back the next day and reopening my workflow, or rather trying to reopen it, I discovered that when things in the code behind file don't make sense, the Workflow Designer can't (and won't) try to clean up your mess. Instead, you get a nice screen that looks like Figure 3
|Figure 3. An Informative WF Error Message: Unhelpfully, WF lets you know that there's an invalid object reference somewhere in your workflow.|
If you see that screen, put your scuba gear on, because you're going code diving. The most likely culprit is that you have a duplicate name somewhere, and you'll have to dig through the WorkflowName.cs
files to clean up the problem.
Occasionally, your workflow might vanish for other reasons—even if you've done everything right.
If that happens, here are two remedies you can try. One way is to right-click on the solution name in the Solution Explorer window and then click "Clean Solution" on the context menu. Click on a tab other than your workflow diagram, and then click back to the designer. That often solves the problem; however, if it fails, restart Visual Studio. If your workflow has no other problems, one or both procedures will usually fix the problem.
While I was untangling my mess, it occurred to me that cleaning it up sure would be easier if I had broken the workflow into custom activities during the design phase. I decided that as long as I was cleaning things up anyhow, it made sense to go ahead and put the various pieces into separate activities (think Custom Controls in Windows Forms.) Coincidentally, this brings me to the fourth Windows Workflow lesson.
Custom Activities Are Your Friends
It's true. Custom Activities are your friends. They may not always act like your friends, and sometimes they may borrow your stuff without asking, never bring it back and claim it was theirs all along, but ultimately
they are your friends.
You should create custom activities whenever it makes sense to do so, either because you intend to reuse an activity in other areas of a larger workflow, other workflows, or just because it helps to break up a much larger workflow (allowing multiple people to work on different areas at once).
To create a custom activity, right-click in Solution Explorer and select Add, then select Activity. I usually create a folder to store all of my custom activities.
Separating workflows into custom activities make maintenance significantly easier and also help to alleviate naming conflicts between similar or identical activities in different parts of the workflow.
No surprise, this brings me to the fifth Windows Workflow lesson.
Some Workflows Require Identical Activities in Multiple Places
One of the great things about Visio is that you can route your "flow" however you like, even if that involves hitting the same activity from different paths. Unfortunately, you can't hit the same activity from multiple paths in a workflow, so you have two choices:
- Duplicate activities in your workflow (with different names of course)
- Create a custom activity with the necessary functionality and add multiple instances of that activity to your workflow.
If you can
accomplish this with a custom activity, you should
do so unless the item is just too small to warrant the effort, such as when the activity has only one step. Again, be sensitive to your activity names, because having two code activities (for example) with the same name will cause you pain later. Depending on how far along you are, you'll have a fun time untangling which activity is which when the Workflow Designer goes bye-bye.
After cleaning up the naming mess and breaking my large workflow into smaller logical pieces, it was time to get back to the business of making my workflow actually flow. I took a look at the various conditional branches in my workflow and added some Boolean flags in the code behind file. With those in place, I began writing rules for the If/Else activities. Within a few minutes I had a nice collection of rules that covered every if and every else in the entire collection of workflows—but something still didn't seem quite right.
That brings up Windows Workflow lesson number six.
They're Called If/Else Activities for a Reason
To work with an If/Else
activity, you give it a name and description (optional), and that's it. All the real functionality goes into the If/Else
branch activities created within the parent container.
You can use this activity in a few ways. If all you need is the standard If/Else
construct, then add a condition to the first branch.
|Author's Note: Typically this is the left branch, but you won't have any trouble spotting it, because you'll see a red circle icon containing a white exclamation mark at the top right corner. These red and white icons indicate tasks you must take before your workflow will build; so be sure to pay attention to them.
To add a condition, click the activity and look at the property sheet. You will see a Condition
property with the now familiar red and white icon. If you click the dropdown list, you will see two available options: "Code Condition" and "Declarative Rule Condition."
Selecting the Declarative Rule Condition adds a couple of extra properties to the sheet and moves the error icon to the next step you need to complete. Clicking the ellipses next to the ConditionName
property displays the Rule Condition Editor (see Figure 4
|Figure 4. The Rule Condition Editor: You assign rule conditions in this built-in editor, which provides IntelliSense assistance.|
The Workflow Rule Editor provides useful IntelliSense for rule writing. After writing a rule for the first branch and close the editor, you'll notice the error icon has finally disappeared (for that activity).
Interestingly, there is rarely a valid reason to write rules/conditions for the Else
part of If/Else
activities. If you need multiple branches, similar to a Select Case
statement, you can add a branch by clicking on the parent If/Else
activity and then clicking "Add Branch" in the property sheet. Alternatively, you can drag another If/Else
activity into your Else
branch, depending on which one makes the most sense for the workflow.
Typically though, you should avoid adding rules or conditions to the Else branch. Note that the designer doesn't display the error icon for that branch, even though it is empty. Adding conditions to this branch is not good practice, because it hides flow logic and could cause problems later on. Usually, if you think you need a condition on your Else branch, chances are what you really need is another branch or another If/Else activity in that part of the flow.
Eventually I got the conditional branches all sorted out, which made me realize there were a few different ways out of my workflow. Depending on the specific conditions, certain branches of the workflow might never execute. This brought me to the seventh Windows Workflow lesson.
Use "Terminate" Activities (Even If You Don't Think You Need Them)
When you're designing your workflow, it's easy to think "I don't need to terminate this section. It just flows right out to the end anyway." Maybe that's true, but what if your workflow gets incorporated into a different workflow, or gets modified after you've started working on something else?
Terminate activities give you a chance to leave a comment about why
you're terminating the flow in that specific spot. They also let you generate an error message if needed, and prevent the workflow from accidentally continuing forward if someone adds more activities between your de facto termination point and the actual end of the workflow.
|Author's Note: Using a Terminate activity in your workflow results in a WorkflowTerminated event rather than WorkflowComplete event, so make sure you process it accordingly.
While wrapping up the design, I decided that it would make more sense to just add the workflow files to an existing project rather than having a separate workflow project. That brings me to the eighth and final (for now) Windows Workflow lesson.
Some Things Are Better Left Alone
I added the existing files to my class library project and did a quick build, no errors. So far so good, so I thought. After the build finished, I continued working and realized that I needed to go back into the workflow designer to make a small change.
Unfortunately, at this point I discovered that the Workflow Designer wouldn't load. Instead I got a rather cryptic error informing me that "the service 'System.Workflow.ComponentModel.Design.IIdentifierCreationService' must be installed for this operation to succeed."
A quick Live Search for the error led me to the MSDN forums for Windows Workflow Foundation, which in turn revealed that adding workflows and activities to a non-workflow project is not supported. Fortunately, it was a trivial exercise to get everything back in order and in its own project again.
Try It for Yourself
Hopefully these "lessons" will prove useful to you (or at least my mistakes may serve as a warning) as you begin your own personal journey into the world of Windows Workflow Foundation.