Plug-in assemblies
Business logic |
---|
|
This document is a brief summary of plug-in assemblies in Resco Cloud and their implementation to the processes (workflows).
Getting started
Plug-in assemblies allow you to run custom C# code on the Resco Cloud as part of the Processes. Plugins can run periodically as jobs or be triggered as workflows. It should solve the limitations of the no-coding editor of processes. There are the typical use cases:
- complex logic of process
- communication with some third party system
- etc.
In Resco Cloud, you can manage plugins using the Admin Console.
Creating a plug-in assembly
- Download Resco SDK.
Sample projects are part of the RescoCRM.Plugin.SDK.zip file. - Create a new project as a Class Library (.NET Framework 4.8 or later).
- Add a reference to the downloaded XRMServer.Core.dll.
- Implement the PluginBase interface.
Return value of plugin
You can define the return value of your plugin.
Implement the IPluginReturnValue interface to the code (e.g. string):
These are the allowed return types: It should be possible to create a variable of this type in Processes editor.
Input values of plugin
You can define the input values of your plugin.
The name of the PluginInputParameter (MyPluginInput in the example), will be visible in the Processes editor.
Logs
context.AppendLogLine("Contacts with specified account id '{0}' cannot be found!", accountId);
Logs are saved and visible in the Admin Console under Processes Center > Logs.
Cancel the workflow execution
context.AppendLogLine("Contacts with specified account id '{0}' cannot be found!", accountId);
return PluginResult.Failed;
Examples
Fetch
Create
Update
Delete
Adding plug-in assembly to the Resco Cloud
In the development tool:
In the Admin Console:
- Go to Processes Center > Plug-in Assemblies.
- Click New, then click Browse and upload the zip file.
The plugin is loaded and the return type and input parameters listed below (if implemented).
Note | If you don't see the plugin in the list, log out and then log back in. |
Executing plugins
- In the Admin Console, go to Processes Center > Processes.
- Click New to create a new process.
- As Category, select Workflow or Job.
- If your plugin has a return value, it is necessary to add the variable of this type to the editor, then you are able to select the plugin.
Process logs
Whenever a process is executed, the run generates a log file entry. To access the logs, go to Processes Center > Logs.
Exporting plugins
If you need to transfer a plugin from one organization to another:
- In the Admin Console, go to Settings > Organization
- Click Export Organization and select Custom.
- Select Plug-ins and click Export.
You can then import the files to the other organization using the Import Organization button.
Alternatively, you can export/import plugins between connected environments.
Exception: There is already an open DataReader
When you fetch data but don't use the result, you can encounter the exception System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first
. To avoid this problem, make sure that all fetch results are used.
Example: Schedule a workflow
One of the possible use cases is to schedule a job with a delay. For example, you have a trigger that executes when a new account record is created. You don't want to perform the follow-up action immediately but after a delay.
Use the following sample to schedule the job.
protected void ScheduleJob()
{
// schedule job
var processService = this.Context.GetService(typeof(IPluginProcessService)) as IPluginProcessService;
if (processService != null)
{
var job = new PluginScheduleJob();
job.Name = $"Scheduled Test Job";
job.RegardingObjectId = new XRMServer.Data.EntityReference(Guid.NewGuid(), "account");
job.TriggerAt = DateTime.Now.AddMinutes(1);
job.TypeName = typeof(Fieldiu.Plugins.accountP).FullName;
job.Data = this.SerializeData(data);
processService.ScheduleJob(job);
}
}
To send data for the job, use the following line:
job.Data = this.SerializeData(data);
In the scheduled job, this is how you can retrieve the data as the input parameter:
object userData;
if (!this.Context.InputParameters.TryGetValue(PluginInputParameterName.UserData, out userData))
return PluginResult.Canceled;
var mySerializedData = (string)userData;
A similar solution can also be useful for long-running jobs. In that case, replace TriggerAt
with job.Recurrence = processService.GetRecurrence(0, 1);
. Keep in mind that long-running jobs (e.g., when generating some statistics) must be stopped after 5 minutes (or they will be aborted by the system). Return PluginResult.InProgress
. Store the current state into data: this.Context.InputParameters[PluginInputParameterName.UserData] = this.SerializeBatchData(result, entity);
. When everything is complete, return PluginResult.Succeeded;