Resco Wiki

Plug-in assemblies

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

  1. Download Resco SDK.
    Sample projects are part of the RescoCRM.Plugin.SDK.zip file.

  2. Create a new project as a Class Library (.NET Framework 4.8 or later).

  3. Add a reference to the downloaded XRMServer.Core.dll.

    Add_reference_to_dll.png
    Add_reference_to_dll_2.png
  4. Implement the PluginBase interface.

    PluginBase_interface.png

Return value of plugin

You can define the return value of your plugin.

Implement the IPluginReturnValue interface to the code (e.g. string):

IPluginReturnValue.png

These are the allowed return types: It should be possible to create a variable of this type in Processes editor.

Allowed_return_type.png

Input values of plugin

You can define the input values of your plugin.

Input_values.png

The name of the PluginInputParameter (MyPluginInput in the example), will be visible in the Processes editor.

MyPluginInput.png

Logs

C
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

C
context.AppendLogLine("Contacts with specified account id '{0}' cannot be found!", accountId);
return PluginResult.Failed;

Examples

Fetch

Example-fetch.png

Create

Example-create.png

Update

Example-update.png

Delete

Example-delete.png

Adding plug-in assembly to the Resco Cloud

In the development tool:

  1. Build the solution.

    Build_solution.png
  2. Create the zip file with the dll file.

    Create_zip.png

In the Admin Console:

  1. Go to Processes Center > Plug-in Assemblies.

  2. 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).

Plugin_successfully_loaded.png

Note

If you don't see the plugin in the list, log out and then log back in.

Executing plugins

  1. In the Admin Console, go to Processes Center > Processes.

  2. Click New to create a new process.

  3. As Category, select Workflow or Job.

  4. 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_using_the_demo_plugin.png

Process logs

Whenever a process is executed, the run generates a log file entry. To access the logs, go to Processes Center > Logs.

Process_log.png

Exporting plugins

If you need to transfer a plugin from one organization to another:

  1. In the Admin Console, go to Settings > Organization

  2. Click Export Organization and select Custom.

  3. 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.

JavaScript
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:

JavaScript
job.Data = this.SerializeData(data);

In the scheduled job, this is how you can retrieve the data as the input parameter:

JavaScript
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;

Last updated: