Let's start developing an actual activity, which mediates between our business logic and our view.
Properties
RPA Designer displays all declared public properties inside an activity as options in the property pane.
These can be used to pass data from the process to the activity. There are two different types of Argument to pass data from the Designer to the activity.
Direct Data Type
If, for example, you create a property of type string, it is possible to pass the desired value directly to the activity. Similar is the case with Enums, which will create a drop-down menu with the enum's values. However, it is not possible to pass this data to a variable that is declared inside the Designer and vice versa.
To pass data from the Designer to the activity and the other way around Workflow Foundation provides for this case the data types In- and OutArgument.
public string CalculationStringNoArgument { get; set;
InArguments
The goal is to pass a variable with previously collected data from the running process to the activity. For this, we use the generic type InArgument, which takes the type via the angle brackets.
public InArgument<string> CalculationString { get; set; }
Now a variable can be passed to the activity. To access the data that is being passed in, we use the context parameter of the execute method (CodeActivityContext context), and with the context.GetValue method we get the desired data.
string calculationString = context.GetValue(this.CalculationString);
Since we use the generic InArgument, the method GetValue returns the correct data type.
OutArguments
OutArgument functions the same as InArgument but as the name implies it is the other way around. Using the context parameter, we can pass variables back to the Designer. With the method SetValue, we pass the variable from the activity to the Designer as the correct data type.
context.SetValue(this.Result, calculationResult);
Enums
Enum's can be used to show drop-down inside the Designer. Enum's must be declared directly and not as In- or OutArgument.
Attributes
To control how Arguments are displayed inside the Designer, attributes can be used before each Argument.
Here is a short list of frequently used attributes:
- Category: Shows the argument inside a specific category on the Properties pane.
- DisplayName: The name of the argument on the Properties pane.
- RequiredArgument: Indicates that the argument needs to be set.
- VariableSelectionOutputPopup/VariableSelectionInputPopup: A popup is displayed when dragging the activity into your workflow. This will prompt the user to specify a variable or enter a value directly. Highly recommended for required arguments.
- Description: A tooltip is shown when hovering over the argument. Additionally, the description is displayed inside the input box.
Metadata
Instead of writing attributes above an argument to change how it's displayed inside RPA Designer, you can use the AM.Skeleton.Activites_metadata.xml for this purpose.
Example
<ProjectMetadata> <Metadata> <ActivityMetadata ActivityType= "AM.Skeleton.Activities.CalculateFromStringActivity"> <DisplayName>Calculate from String</DisplayName> <Description>Calculates a math formula from a string</Description> <Category>Math</Category> <SearchTags>calculate, math, from string</SearchTags> <PropertiesMetadata> <PropertyMetadata PropertyName= "Result" DisplayName= "Result" RequiredArgument= "true" HintText= "Integer" Category="Output" VariableSelectionInputTextPopup= "false" VariableSelectionInputVariablePopup= "false" VariableSelectionOutputPopup= "true" Order="0" /> <PropertyMetadata PropertyName= "CalculationString " DisplayName= "Calculation String" Description= "String with the math formula" RequiredArgument= "false" HintText= "Boolean" Category="Options" VariableSelectionInputTextPopup= "false" VariableSelectionInputVariablePopup= "false" VariableSelectionOutputPopup= "true" Order="1" /> </PropertiesMetadata> </ActivityMetadata> </Metadata> </ProjectMetadata
Synchronous Activities
Most common activites are synchronous.
Your type should inherit from AbstractCodeActivity or from a type that does. AbstractCodeActivity contains an abstract method that you need to overwrite. To pass arguments into your business logic, use context.GetValue(). After processing the value, you can then return it to RPA Designer using context.SetValue().
Example
protected override void Execute(CodeActivityContext context) { string calculationString = context.GetValue(this.CalculationString); Console.WriteLine(calculationString); ICalculatorApplication calcApp = new CalculatorApplication(); int calculationResult = calcApp.CalculateFromString(calculationString); context.SetValue(this.Result, calculationResult); }
You should add error handling to the activity to show for example when arguments are left empty.
Async Activites
If you have a long-running task its best to run it on a separate thread, after the task is complete, you can use the type AbstractTaskAsyncCodeActivity.
If your task needs to return a value, you need to use the type AbstractTaskAsyncCodeActivity<T>
Async without result example
public class AsyncActivity : AbstractTaskAsyncCodeActivity { public InArgument<string> FilePath { get; set; } private static async void HandleFileAsync(string file) { /// Long running task } protected override Task ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { string file = FilePath.Get(context); return Task.Factory.StartNew(() => HandleFileAsync(file), cancellationToken); } }
For an async with result example take a look inside the Skeleton activity.