Custom Workflow – Concepts
Concept
Microsoft Dynamics 365 (online & on-premises) supports the registration and execution of custom workflow activities in addition to the out-of-box activities provided by Windows Workflow Foundation. Windows Workflow Foundation includes an activity library that provides activities for control flow, sending and receiving messages, doing work in parallel, and more. However, to build applications that satisfy your business needs, you may need activities that perform tasks specific to that application. To make this possible, Windows Workflow Foundation supports the creation of custom workflow activities.
Custom Workflow Activities (CWAs) are the custom CRM activity steps i.e. technically a .net assembly which are being used as a step in CRM workflows to achieve some business task which can be done using simple CRM workflow options.
Here in this topic we will cover to understand the basics of custom workflow activity, how to develop it and test it by deploying in CRM organization.
To develop a custom workflow you need to have:
- Visual Studio IDE
- Dynamics 365 SDK – Plugin Registration Tool
- Simple Knowledge on C#.NET
Required Reference Dlls
- Microsoft.Xrm.Sdk.dll
- Microsoft.Xrm.Sdk.Workflow.dll
- System.Runtime.Serialization
Required Namespaces
using System.Activities; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Workflow;
Remember
- Custom workflows can be incorporated by CRM workflows or Dialogs as a process step. Custom workflows cannot be run independently as these are treated as a process step inside a CRM workflow or Dialog.
- Every workflow supports some Input Parameters and Output parameters.
- Input Parameters are supplied to the custom workflow from the CRM workflow and Output parameters are returned from the custom workflow to CRM workflow to use in check condition steps.
- After developing the custom workflow assembly it is registered in CRM using plugin registration tool the same way we do for plugins.
- Custom workflow activities are .net assemblies which are registered in CRM.
- Every custom workflow activity class inherits CodeActivity class.
- Each custom workflow assembly must be signed in by a KEY.
More Information
Microsoft Dynamics CRM supports two types of parameters for a workflow activities.
1. Input Parameters
2. Output Parameters
Input Parameters
The input parameter is annotated with the .NET attribute “Input”.
Default Value
While specifying the input parameter in your workflow class, you can also specify a default value for the parameter.
Sample Parameters given below.
For Boolean Type(Input) [Input("Bool input")] [Default("True")] public InArgument BoolFlag { get; set; } For Boolean Type(Output) [Output("Bool input")] public OutArgument BoolFlag { get; set; } For Boolean Type (Both Input and Output) [Input("Bool input")] [Output("Bool output")] [Default("False")] public InOutArgument BoolFlag { get; set; } DateTime [Input("DateTime input")] [Output("DateTime output")] [Default("2013-07-09T02:54:00Z")] public InOutArgument DateTime { get; set; } Decimal [Input("Decimal input")] [Output("Decimal output")] [Default("20.75")] public InOutArgument Decimal { get; set; } Double [Input("Double input")] [Output("Double output")] [Default("200.2")] public InOutArgument Double { get; set; } Integer [Input("Int input")] [Output("Int output")] [Default("2322")] public InOutArgument Int { get; set; } Money (Currency) [Input("Money input")] [Output("Money output")] [Default("232.3")] public InOutArgument Money { get; set; } OptionSetValue [Input("OptionSetValue input")] [Output("OptionSetValue output")] [AttributeTarget("account", "industrycode")] [Default("3")] public InOutArgument OptionSetValue { get; set; } String [Input("String input")] [Output("String output")] [Default("string default")] public InOutArgument String { get; set; } Entity Reference [Input("EntityReference input")] [Output("EntityReference output")] [ReferenceTarget("account")] [Default("3B036E3E-94F9-DE11-B508-00155DBA2902", "account")] public InOutArgument AccountReference { get; set; }. Required Argument Attribute System.Activities.RequiredArgumentAttribute class can be used to specify that the input parameter is required. [RequiredArgument] [Input("Update next Anniversary date for")] [ReferenceTarget("contact")] public InArgument Contact { get; set; } Output Parameters The output parameter is annotated with the .NET attribute "Output" //this is the name of the parameter that will be returned back to the workflow [Output("Credit Score")] //this line identifies the specific attribute which will be passed back to the workflow [AttributeTarget(CustomEntity, "new_creditscore")] //this line declares the output parameter and declares the proper data type of the parameter being passed back. public OutArgument CreditScore {get;set;}
DEVELOP
To develop a custom workflow activity we need a requirement first. Below is a requirement for which we will create a custom workflow and call this in a CRM workflow.
Requirement: While creating a customer the user will supply the date of birth and the system will auto calculate that Age and populate on customer form.
Solution : This will be done by a Real-time workflow using a Custom workflow activity.
Watch the video for practical steps:
DEBUG
To debug a custom workflow activity, copy the .pdb file for the assembly to the %installdir%\server\bin\assembly folder. The assembly can be deployed as on-disk or stored in the database. The recommended deployment is in the database, but for debugging you should select on-disk. Next, attach the debugger to the CrmAsyncService.exe process.
The below code is used as a custom Workflow activity.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Activities; using Microsoft.Xrm.Sdk.Workflow; namespace GetAge { public sealed class CalculateAge:CodeActivity { [Input("Date Of Birth")] public InArgument<DateTime> DOB { get; set; } protected override void Execute(CodeActivityContext context) { DateTime dtDOB = DOB.Get(context); int CalculatedAge = Convert.ToInt32((DateTime.Now.Subtract(dtDOB).TotalDays)/365); Age.Set(context, CalculatedAge); } [Output("FinalÄge")] public OutArgument<Int32> Age { get; set; } } }
Thanks for your time. Please subscribe the channel and follow the site for more tutorials.