UiPath Studio

Building Custom Rules

Workflow Analyzer is a tool for making sure your project follows best practices, maintainability, readability, performance, reusability, reliability, and security requirements.

These concepts are important for ensuring clean and reliable workflows that can sum up large automation projects.

Note:

To build custom rules, you need the UiPath.Activities.Api package from the Official feed.

In its off-the-shelf form, Workflow Analyzer is integrated into Studio and incorporates validation and analyzer capabilities. Analysis cannot be done if validation returns errors.

Workflow Analyzer Concepts

In order to build custom rules for your project, a number of concepts should be defined to better understand how Workflow Analyzer works behind the scenes.

Important!

When building custom rules, please target the .NET Framework version 4.6.1.

Rules and Counters

Workflow Analyzer makes use of certain criteria to ensure project reliability is met. These checks are performed using carefully defined rules and counters.

A rule represents a requirement that must be met. It can be set to check the inspection object against the rule definition.

A counter represents a check done for revealing the number of times a particular event or condition has occurred.

For each unmet rule, a message is listed in the Error List panel in the form of a warning, error, info, or verbose messages. These listings also contain recommendations for making changes and ensuring rules are met.

Note:

When creating custom rules and counters, make sure to follow the naming convention detailed in the About Workflow Analyzer page.

Inspection Object

Workflow Analyzer is capable of performing an in-depth analysis of a predefined object. The object represents the scope to be analyzed, the area in which the rule or counter is enforced.

Creating Rules

From the Official feed (https://www.myget.org/F/workflow), install the UiPath.Activities.Api package.

To help you create a custom rule, let's look at a current predefined rule in the Workflow Analyzer, Variable Length Exceeded. This rule checks whether the length of variables defined in the project is smaller than 20 characters. The rule's inspection object is activity.

Behind the scenes, the rule looks like this:

// This static class is not mandatory. It just helps organizining the code.
internal static class VariableLengthRule
    {
  // This should be as unique as possible, and should follow the naming convention.
        private const string RuleId = "ST-NMG-008";

        internal static Rule<IActivityModel> Get()
        {
            var rule = new Rule<IActivityModel>("Variable Length Rule", RuleId, Inspect)
            {
                RecommendationMessage = Recommendation,
              /// Off and Verbose are not supported.
                ErrorLevel = System.Diagnostics.TraceLevel.Warning
            };
            return rule;
        }
  
  			// This is the function that executes for each activity in all the files. Might impact performance.
        // The rule instance is the rule provided above which also contains the user-configured data.
 				 private static InspectionResult Inspect(IActivityModel activityModel, Rule ruleInstance)
        {
            var messageList = new List<string>();
            foreach(var activityModelVariable in activityModel.Variables)
            {
                if (activityModelVariable.DisplayName.Length > 20)
                {
                    messageList.Add($"The variable {activityModelVariable.DisplayName} has a length longer than 20");
                }
            }

            if (messageList.Count > 0)
            {
                return new InspectionResult()
                {
                    ErrorLevel = ruleInstance.ErrorLevel,
                    HasErrors = true,
                    RecommendationMessage = ruleInstance.RecommendationMessage,
                  // When inspecting a model, a rule can generate more than one message.
                    Messages = messageList
                };
            }
            else
            {
                return new InspectionResult() { HasErrors = false };
            }
        }
    }

The RuleId parameter requires the name of your rule. In this example, the Variable Length Exceeded rule carries the ST-NMG-008 rule ID and follows the Rule Naming Convention.

The RecommendationMessage parameter requires a message to be displayed as a recommendation to help the user solve any inconsistencies found after the analysis is done. The message should be succinct and offer clear steps.

The ErrorLevel parameter states the default action to be taken in case the condition isn't met. In this example, the rule throws a warning. Default actions can be error, warning, info or verbose.

Build rules with parameters

The situation changes slightly when we want to build rules that contain customizable parameters. One of such rules is Variables Naming Convention. Its inspection element is activity and carries a default Regex expression, which can be changed.

Behind the scenes, this rule looks like this:

internal static class VariableNamingRule
    {
        private const string RuleId = "ST-NMG-001";
        private const string RegexKey = "Regex";
        private const string DefaultRegex = @"^([A-Z]|[a-z])+([0-9])*$";

        internal static Rule<IActivityModel> Get()
        {
            var rule = new Rule<IActivityModel>(Strings.ST_NMG_001_Name, RuleId, Inspect)
            {
                RecommendationMessage = Recommendation,
                ErrorLevel = System.Diagnostics.TraceLevel.Warning
            };
            rule.Parameters.Add(RegexKey, new Parameter()
        }
                                
       private static InspectionResult Inspect(IActivityModel activityModel, Rule ruleInstance) 
        {
          // This retrieves the parameter value from the rule instance as configured by the user, if not, the default value.
            var setRegexValue = ruleInstance.Parameters[RegexKey]?.Value;
          
            var regex = new Regex(setRegexValue);
            var messageList = new List<string>();
            foreach (var activityModelVariable in activityModel.Variables)
            {
                if(!regex.IsMatch(activityModelVariable.DisplayName))
                {
                    messageList.Add(string.Format(Strings.ST_NMG_001_ErrorFormat, activityModelVariable.DisplayName, setRegexValue));
                }
            }

            if(messageList.Count > 0)
            {
                return new InspectionResult()
                {
                    ErrorLevel = ruleInstance.ErrorLevel,
                    HasErrors = true,
                    RecommendationMessage = ruleInstance.RecommendationMessage,
                    Messages = messageList
                };
            }
            else
            {
                return new InspectionResult() { HasErrors = false };
            }
        }
    }

Notice it calls the RuleId, RegexKey and DefaultRegex which is the default Regex expression associated with this rule.

The RecommendationMessage and ErrorLevel parameters are the same as for the previously presented rule.

Build Counters

Counters represent checks done for revealing the number of times a particular event or condition has occurred.

Their structure is a bit different from that of rules, in the sense that the only available ErrorLevel parameter for counters is Info. Therefore, the expression for defining the error level for a counter should look like this ErrorLevel = System.Diagnostics.TraceLevel.Info.

Let's take File Activities Stats as an example of how counter rules look behind the scenes:

internal static class NumberOfActivitiesInFile
    {
        private const string RuleId = "ST-ANA-009";

        internal static Counter<IActivityModel> Get()
        {
            return new Counter<IActivityModel>(Strings.ST_ANA_009_Name, RuleId, Inspect);
        }
  
  // A Counter<T> receives the entire collection of T objects in the parent structure. e.g. activities in workflow, workflows in project.
  private static InspectionResult Inspect(IReadOnlyCollection<IActivityModel> activities, Counter ruleInstance)
        {
            return new InspectionResult()
            {
              // For a counter, the error level is always info, even if not set here.
                ErrorLevel = System.Diagnostics.TraceLevel.Info,
              // For a counter, the Has Errors field is always ignored.
                HasErrors = false,
                Messages = new List<string>() { string.Format(Strings.ST_ANA_009_ErrorFormat,  activities.Count) }
            };
        }

Rules Registration

Registration Interface Method

Please bear in mind that by using this method, your package is compatible only with Studio versions 2019.10 or higher.

Implement the IRegisterAnalyzerConfiguration interface with the following method Initialize(IAnalyzerConfigurationService workflowAnalyzerConfigService).

using UiPath.Studio.Activities.Api;
using UiPath.Studio.Activities.Api.Analyzer;
using UiPath.Studio.RulesLibrary.Rules.Naming;

namespace UiPath.Studio.RulesLibrary
{
    public class RegisterAnalyzerConfiguration : IRegisterAnalyzerConfiguration
    {
        public void Initialize(IAnalyzerConfigurationService workflowAnalyzerConfigService)
        {
            // Naming
            workflowAnalyzerConfigService.AddRule(VariableNamingRule.Get());
            workflowAnalyzerConfigService.AddRule(DisplayNameDuplicationRule.Get());
            workflowAnalyzerConfigService.AddRule(VariableNameDuplicationRule.Get());
            workflowAnalyzerConfigService.AddRule(ArgumentNamingRule.Get());
            workflowAnalyzerConfigService.AddRule(VariableLengthRule.Get());
        }
    }
}

IRegisterMetadata Method

Please note that this method is available only for Studio versions higher than 2019.6, and it's not as suitable as the registration interface method.

  • Add a method void Initialize(object api) to your implementation of IRegisterMetadata.
  • In your Initialize implementation cast the object parameter to WorkflowDesignApi, and add everything under a Try Catch just to make sure any exceptions are managed.
  • Once you resolve the WorkflowDesignApi api, the WorkflowAnalyzerConfigService is available as a property.
  • At this point, you have access to the IAnalyzerConfigurationService detailed in the section above.

Add Rules to Studio

Custom Workflow Analyzer rules can be integrated in Studio in two ways:

  • at global level by adding the external assembly (.dll) in the Studio install location
  • at project level by installing the custom activities pack.

At Global Level

To make custom rules available for all projects created in your instance of Studio, add the external assembly (.dll) package to the install location.

Follow the steps detailed in the Creating a Custom Activity page to export the code as a .dll file.

The exported file must now be added to Studio install location:

  • .msi: C:\Program Files (x86)\UiPath\Studio\Rules
  • .exe: %localappdata%\UiPath\Rules.

At Project Level

To make custom rules available only for a certain project, create a NuGet package (.nupkg) and install it in a Studio project as a dependency, as detailed here.

Updated 29 days ago



Building Custom Rules


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.