Workflows – Introduction
Workflows are one of the most useful and underrated features of Microsoft Dynamics CRM 2011 development. Xaml workflow allows you to write workflows without having to use any C# code (well, it’d be more correct so say ‘generally allows you to’, there are some exceptions – but in those cases, you can create your own Activity classes, reference them and use them visually. The only important caveat is that you can’t use Coded Workflows w/ Microsoft CRM Online, but that is the case whether or not it’s coded or purely XAML). The OOB Workflow designer lets you do quite a bit without ever having to write a line of code. And for the places where the OOB Designer doesn’t meet your needs, you can open Visual Studio 2010/2012 and code whatever you want.
For the most part, writing a coded workflow for Microsoft Dynamics CRM 2011 is virtually identical to writing a Plugin. You still have to deal with the hassle of external references, you still have to use the Plugin Registration tool and for the most part, it’s 6 of one, 1/2 dozen of another. This hasn’t changed much from CRM 4.0 other than the refinements in the SDK in general.
Workflow Foundation (as well as Windows Communication Foundation for that matter) itself however has underwent some major changes in version 4.0. If I had to describe the changes in one sentence, it’d be “Workflow Foundation 4.0 is designed to absolutely minimize the amount of code that a developer will have to write”. In real terms, that means that you are using visual tools and largely dragging, dropping and configuring. The main downside is that it’s effectively a new skillset (yes, there were visual elements with previous versions, but you couldn’t get too far down any path without having to use Code Activities and at that point, things are pretty much the same as regular .NET development).
Unlike Sharepoint 2010, Dynamics CRM 2011 makes use of the latest version of Workflow Foundation. Additionally, CRM 2011 introduced the concept of Solutions (which are totally different from Visual Studio Solutions). If you opt to use pure XAML workflows, you don’t have to use the Plugin Registration tool and can deploy and activate the workflows via the solution. If you’ve ever dealt with the headaches of having to register several plugins/workflows and their corresponding steps, you’ll quickly learn to love the fact you can’t dispense with it if you just bite the bullet and adopt the Workflow Foundation 4.0 methodology. Yes, there are going to be a few cases where you absolutely can’t get around using Code Activities (and at that point, you’ll need to use the Registration Tool) but you’d be really amazed at how much you can do using purely visual methodology. Additionally, anyone that can put together a Visio diagram can build a XAML based workflow, outside of code activities you don’t need to know a single line of C# or VB.NET. Suffice to say there are major benefits and incentives to doing the pure XAML thing where possible.
With that said, there are two really big frustrations in adopting the new approach. The first is simply unlearning your regular way of doing things and using the visual components. If you can’t deal with this, you’re in the wrong line of work. If learning new things and new ways of doing things is more work than fun, a development career is going to be on long road full of frustration. The other big frustration (and IMHO, quite a legitimate one) is that even though CRM workflows are pure Workflow Foundation, to get them to work you have to know a bunch of information that isn’t intuitive and isn’t well documented. In fact, I’ve been searching for weeks on both Google and Bing for a standard tutorial that really covers all you need to know to build and deploy a WF 4.0 Workflow for CRM and haven’t found one. Each of those things is something I’ve had to learn the hard way. While the SDK examples are enough to give you a theoretical understanding, they leave a lot uncovered that you’ll immediately be troubled with if you try to do anything other than non-trivial contrived samples.
Developer Toolkit for Microsoft Dynamics CRM 2011
There’s a Developer Toolkit for Microsoft Dynamics CRM 2011 which is continually updated which includes many features which can be of great assistance. If you use the Project Templates, much of the items below should be done for you. However it’s important to understand why things work so you can troubleshoot them and get things done on your own if you have any problems with the Templates. I highly recommend looking through the
So to get started and not run into hangups throughout the process, let’s go through the most common areas that you’ll likely have issues with and that aren’t documented very well, if at all:
Set Up Your Toolbox:
Open up Visual Studio 2010 and if you’re ToolBox isn’t already displayed, select View [Alt +V] -> Toolbox [Ctrl + W, X]. If you have a Workflow Library or Project already opened, your toolbox will look approximately like Figure 1-1.
Figure 1-1 – Workflow Foundation 4.0 Default Toolbox.
Now, you’ll want to add all of the required workflow dll references to your project (Microsoft.Xrm.Sdk, Microsoft.Xrm.Sdk.Worfklow and any others you know you’ll need). After adding these References to your project, you’ll want to add the visual components to your Toolbox. To do this right click inside the surface of the Toolbox and choose Add Tab (this isn’t technically required but will allow you to group all of Microsoft.Xrm.Sdk.Workflow activity items in one area) and name it something intuitive, CRM 2011 works for me.
Choose Toolbox Items:
Next right click inside the surface again and select the Choose Items… context menu item. Select the System.Activities Components tab and press the Browse button as shown below:
Figure 1-2 – Choose Toolbox Items Dialog
Browse to the location of the SDK->bin folder and select the Microsoft.Xrm.Sdk.Workflow.dll . After selecting the Microsoft.Xrm.Sdk.Workflow.dll file and pressing Ok, all of the Activity items included in that library will be available in the System.Activities Components tab.
First, sort on the Name column in ascending order. Find the Assign<T> activity (System.Activities.Statements namespace, System.Activities (18.104.22.168) Assembly Name) and choose it. This works almost identically to the standard Assign activity, but it lets you specify a type which is very important when building Dynamics CRM 2011 Workflows.
Next sort on the Namespace column and find the series of Microsoft.Xrm.Sdk.Workflow.Activities Namespace. For simplicity, just select each of these (making sure you still have the Assign<T> activity checked) and pretty OK. The dialog box should close and your toolbox should now have all of the new items listed under the CRM tab created earlier. If done correctly, your toolbox should look like Figure 1-3 (Note the image has all the other tabs collapsed just for readability, all the items inside those tabs are still there):
Figure 1-3 – CRM Toolbox Tab with Workflow Activities Added:
At this point, you’ll have all the CRM Activities that you’ll need to use for most development tasks. Keep in mind one thing up front… In almost all cases where you’d use the Assign activity in your workflow in non-CRM projects, you’ll need to use the Assign<T> activity here (and specify Microsoft.Xrm.Sdk.Entity in the type definition. It’s possible you’ll use other SDK types (like Microsoft.Xrm.Sdk.EntityReference) but most of the time it’ll be Microsoft.Xrm.Sdk.Entity.
Adding References to Imports:
Even if you’ve already added Assembly References to your Workflow project, and even if you’ve already set up your toolbox with the CRM Assemblies, you still need to specify the references you’ll use in your workflow or they be available in your Activities (which means things won’t compile). In general, you’ll need the following Assemblies (you may need more depending on your project but most every workflow will need at least these):
- Microsoft.Crm.Sdk.Proxy.dll (Optional)
- Microsoft.Xrm.Client.dll (Optional)
- Microsoft.Xrm.Portal.dll (Optional)
- System.Diagnostics (Optional)
- Enterprise Library Dlls if you’re using the Enterprise Library
- Any other libraries you use or activity libraries you have created
Once you’ve added each of these to the Project by using the Add Reference dialog, you’ll also need to add them to the workflow itself. To do this, select the Imports tab at the bottom left of the window. This will show you what Assemblies have already been imported so you’ll just need to add the ones you’ve referenced which aren’t showing in the Imports section. If you’ve already added the Project Reference, this is extremely easy. At the top of the dialog, you’ll see a Textbox containing the text Enter Or Select Namespace. Just type the full namespace name in for each of the assemblies you want to include (you should get auto-fill support to help you entering it if you’ve added the project reference already). Take a look at Figure 1-4 below, it shows you an example with the Microsoft.Xrm.Sdk and Microsoft.Xrm.Sdk.Workflow assembly references added already.
Figure 1-4 – Imports Dialog
Adding Arguments Values:
After these have been added (and any others you deem necessary), click on the Workflow Designer Canvas and select the Arguments tab at the bottom left of the window. It’s shown in Figure 1-5 below:
Figure 1-5 - Arguments Window in Workflow Designer
If you export a Workflow via the Solution and open it in Visual Studio, the two Arguments shown above [ InputEntities , CreatedEntities ] will be included by default. If you are coding your own Workflow from scratch, you’ll need to add these yourself. You can use other names for them, but in my experience doing so will lead to many unnecessary headaches without adding any value. So just use the names that CRM uses by Default. They should both have In specified for their Direction and the Argument Type should be IDictionary<String, Entity> for both. You’ll have to browse the type list . If added correctly, you’ll see the types specified as they are in the previous image. To get there, click in the Argument Type drop down, select Browse For Types. It’s easiest to just type in System.Collections.Generic.IDictionary in the Type Name field so you don’t have to hunt for it (and it’s a little difficult to find b/c the System.Collections.Generic library referenced by default doesn’t contain IDictionary). Once you select System.Collections.Generic.IDictionary you’ll see two drop downs available for the Key and the Value type. Specify System.String for the Key, and Browse to Microsoft.Xrm.Sdk to select Entity for the value). If you’re selecting them, your dialog should look like Figure 1-6.
Figure 1-6 – Browse Types Dialog
The last step is Optional although something you’ll frequently want/need to do. If you are going to use any Variables, you need to define them up front. If you attempt to reference a variable that hasn’t been declared, or that was declared in the wrong scope, you’re activity (and any parent containers) won’t validate. Variables can be scoped at essentially any level you want. This means they can be scoped to have visibility throughout the whole workflow, any given sequence, any given activity etc. The same rules of scope apply to workflows that apply to any other code you’d right – you want to grant as much visibility as needed to get the job done but not any more.
There are two ways to determine the scope.
First, if you click on the Item itself and chose the Variables window, you’ll see whatever variables are defined or available to that component.
Second, look at the Scope column in the Variables grid. This grid shows you each of the variables that are available in the given scope, the Variable Type, the Scope and the Default Value if you specify one (and one really cool feature regarding Default Values is that you can use both hard coded values as well as Expressions. This allows you to dynamically determine essentially ‘hard coded’ default values). More on this later in the series.
In any case, for my example, I have no Variables defined at the Workflow level. I have a Sequence which serves as the container for all my other Activity items (the Sequence is contained by the Workflow). So, if you look at the available variables for the Sequence (Named Step1 – Create Email) or any of the contained activities, you’ll see the same set of variables. If you select the Workflow component, you won’t see any variables). Figure 1-7 illustrates this:
Figure 1-7 - Arguments Window in Workflow Designer
InputEntities & CreatedEntities:
Earlier in the discussion I mentioned that there are two Arguments that are created by default every time CRM Creates a Workflow and that it’s highly advisable for you to use the same naming conventions and standards. By doing so, you make sure that data can come into your workflow and be extracted from it without any additional work.
Keep something in mind. Workflows (as opposed to other Processes) in CRM are associated with a specific entity type. Along with that Microsoft.Xrm.Sdk.Entity type, they’re associated with one or more Actions (for instance, Create, Update, Delete). So just to make things a little more clear, let’s say that we have a Workflow defined to run when a new Contact is created. Assume that a new contact is created. The InputEntities parameter is a IDictionary<String, Entity> collection. If you just have one workflow associated with one entity (in this case Contact), there will only be one item in the InputEntities collection. B/c you have to reference it using a String Key, consistency is everything. By default, you use for a creation operation:
For an update, you’d use:
I’m still trying to find out what the key value of additional entities (for instance, executed in child workflows) would be. They implemented InputEntities as a collection for a reason, so I have to assume there can/will be more than one entity stored in it. At the moment I haven’t been able to find out much more about it, but I’m actively looking into it and will update this post accordingly.
So this sums up the main stumbling blocks you’re likely to encounter when you’re going to roll out your own workflows. If you have everything setup as shown above, you can just jump right in and start adding your Activities and put together a comlpete workflow. When you’ve got it finished, you can just copy the xaml files over to the Workflows folder of your Solution and import it. For further reading, I’d recommend that you read Create and Deploy XAML Workflows using the Developer Toolkit which is where I started my quest to get my questions answered.
KeyWords: Dynamics4, Dynamics4.com, Microsoft.Xrm.Sdk.Entity, Crm 2011, Dynamics CRM 2011, Microsoft.Xrm.Sdk.Workflow, Microsoft.Xrm.Sdk, Microsoft Dynamics CRM 2011, XAML, InputEntities(“primaryEntity”), InputEntities(“updateEntity”), Developer Toolkit for Microsoft Dynamics CRM 2011, Microsoft.Xrm.Sdk.Entity, Assign<T>, Assign Activity, Workflow, Sequence Activity, Workflow Foundation 4.0