Skip to main content

PreConnect Trigger

  • PreConnect Trigger programs are executed while a new Relationship Instance is being created.
  • They are used to validate or manipulate the instances based on business requirements.
  • They are executed synchronously, i.e. in the same transaction as the relationship instance creation.
  • They are executed before standard validations are executed by the platform code.

Coding guidelines

  • PreConnect Trigger program is a class that must implement the interface IPreConnectTriggerProgramAsync

    public interface IPreConnectTriggerProgramAsync
    {
    Task<ProgramResult> RunAsync(Relation relation);
    }

    NOTE: Implement IPreConnectTriggerProgramAsync with the RunAsync method to enable asynchronous, scalable trigger logic. Most internal service methods are now async, and their synchronous versions are deprecated and will be removed. Use RunAsync to ensure compatibility with these changes.

  • Protrak runtime passes Relation object having information about the instances being linked to the trigger.

    • RelationId: The Guid that uniquely identifies the relationship instance.
    • RelationTypeName: The Relation Type name in Protrak schema using which the instances are being connected
    • Direction: Enum of type Enum.RelationDirection having values "To" or "From" indicating the direction. The direction will decide which instance type will be present in source and destination instances.
    • SourceInstanceId: If the direction is "To" the "From type" instance id as per the relation type definition. If the direction is "From", the "To type" instance id as per the relation type definition.
    • DestinationInstanceId: If the direction is "To" the "To type" instance id as per the relation type definition. If the direction is "From", the "From type" instance id as per the relation type definition.
    • RelationAttributes: Attribute[] having the relation attribute values.
  • Program should return a ProgramResult object:

    • If IsSuccess is true, then the trigger execution is considered as successful.
    • If IsSuccess is false, then the trigger is considered as failed, subsequent code is not executed, and the DB transaction is rolled back.
    • If IsSuccess is false, ideally the string[] Errors should be populated with proper error messages which will be returned in API response, which can be displayed to end user.

Typical use cases for PreConnect Trigger

  • Validate the instances being linked where some business logic is involved.

Anti-patterns or when not to use PreConnect Trigger

  • Do not use PreConnect trigger to make changes that are not reversible, like sending an email. If the connect process fails, the transaction will be rolled back, but the email would have been sent already!

Sample Code

public class PlantToCylinderPreConnectTrigger : IPreConnectTriggerProgramAsync
{
public IInstanceService InstanceService { get; set; }

private readonly string ATTRIBUTE_CYLINDER_LOCATION = "CylinderLocation";

public async Task<ProgramResult> RunAsync(Relation relation)
{
//RelationTypeName: PlantToCylinder. From type: Plant, To type: Cylinder.
var plantInstanceId = (relation.Direction == Protrak.API.Contracts.Enum.RelationDirection.To) ?
relation.SourceInstanceId :
relation.DestinationInstanceId;

var cylinderInstanceId = (relation.Direction == Protrak.API.Contracts.Enum.RelationDirection.To) ?
relation.DestinationInstanceId :
relation.SourceInstanceId;

var plantInstance = await InstanceService.GetInstanceAsync(plantInstanceId, new String[] { "Name", "TrackingId" });
var cylinderInstance = await InstanceService.GetInstanceAsync(cylinderInstanceId, new String[] { ATTRIBUTE_CYLINDER_LOCATION, "TrackingId" });

var errorMessages = ValidateRelation(plantInstance, cylinderInstance);
if (errorMessages.Length == 0)
{
return new ProgramResult() { IsSuccess = true, Errors = null };
}
else
{
return new ProgramResult() { IsSuccess = false, Errors = errorMessages };
}
}

private string[] ValidateRelation(Instance plantInstance, Instance cylinderInstance)
{
//validation code here
return new string[] { };
}
}

Note: The Run method (from IPreConnectTriggerProgram) should only be used if the trigger logic is fully synchronous, does not involve any service/API calls, and consists only lightweight in-memory operations.