Business Integration Solutions SaaS

How to: Create a Custom Codeunit with Expression Functions using the Namespaced Invokable interface

Concept

The Invokable Namespace interface exposes several functions in a codeunit. This is more flexible than Invokable0..10.

Steps

This scenario groups methods under one namespace (codeunit). It requires an enum extension based on TICNSInvokable from STAEDEAN-Common, where you add a new enum value for each library.

enumextension 50000 "My NS Invokable Enum Ext" extends TICNSInvokable
{
  value (50000; "My custom function list")
  {
    Implementation = TICINamespacedInvokable = "My custom function list", TICIInvokeRegistrable = "My custom function list";
  }
}

Your codeunit must implement both interfaces: TICINamespacedInvokable and TICIInvokeRegistrable.

The TICINamespacedInvokable interface exposes the Invoke method, where you call every function you need. It has the following definition:

// <return>Will hold the method execution result</return>
// <method>The method name to invoke</method>
// <args>An array holding the required arguments for your method call</args>
procedure Invoke(var return: Variant; method: Text; args: array[20] of Variant);

The TICIInvokeRegistrable interface exposes the RegisterInvokableMethods method, where you register the functions to make available. It has the following definition:

// <Registrar>Library that exposes ways of registering methods and arguments</Registrar>
procedure RegisterInvokableMethods(var Registrar: Codeunit TICInvokableRegistrar);

// <MethodName>The method name to register</MethodName>
// <MethodDescription>The method description to register</MethodDescription>
// <ReturnType>The method return type</ReturnType>
// <Namespace>The enum value linked to the codeunit library to register</Namespace>
procedure RegisterMethod(MethodName: Text[245]; MethodDescription: Text[150]; ReturnType: Enum TICInvokableReturnType; Namespace: Enum TICNSInvokable)

// <ArgName>The argument name to register</ArgName>
// <ArgType>The argument type to register</ArgType>
procedure AddArguments(ArgName: Text[120]; ArgType: Enum TICInvokableParameterType)

// <MethodName>The argument name to register</MethodName>
// <Namespace>The argument type to register</Namespace>
// The var variables fill with the method metadata based on the method name and namespace
procedure GetMethodMetadata(MethodName: Text[245]; Namespace: Text; var MethodDescription: Text[150]; var ReturnType: Enum TICInvokableReturnType; var ArgumentsList: Codeunit TICInvokableMethodParamColl): Boolean

Example

A full example using the namespaced invokable scenario. Note that only one of the three functions being registered is visible.

codeunit 50000 "My custom function list" implements TICINamespacedInvokable, TICIInvokeRegistrable
{
  procedure XCOPYSTR(String : Text;Position : Integer;Length : Integer) : Text
  begin
    // category : string
    // description: Copies a substring of any length from a specific position in a string (text or code) to a new string.
    exit(copystr(String,Position,Length));
  end;

  procedure Invoke(var return: Variant; method: Text; args: array[20] of Variant)
  begin
    case Method of
      'XCOPYSTR':
        return := XCOPYSTR(args[1], args[2], args[3]);
      'XCOMPANYNAME':
        return := XCOMPANYNAME();
      'Base64Decode':
        return := Base64Decode(args[1]);
      'Base64Encode':
        return := Base64Encode(args[1]);
    end;
  end;

  procedure RegisterInvokableMethods(var Registrar: Codeunit TICInvokableRegistrar)
  var
    ReturnType: Enum TICInvokableReturnType;
    ParameterType: Enum TICInvokableParameterType;
    NSInvokable: Enum TICNSInvokable;
  begin
    Registrar.RegisterMethod('XCOPYSTR', 'Copies a substring of any length from a specific position in a string (text or code) to a new string.', ReturnType::Text, NSInvokable::"BIS Function List 2");
    Registrar.AddArguments('String', ParameterType::Text);
    Registrar.AddArguments('Position', ParameterType::Integer);
    Registrar.AddArguments('Length', ParameterType::Integer);
    Registrar.RegisterMethod('XCOMPANYNAME', 'Gets the current company name.', ReturnType::Text, NSInvokable::"BIS Function List 2");
    Registrar.RegisterMethod('Base64Decode', 'Decodes a base64 encoded value to a string', ReturnType::Text, NSInvokable::"BIS Function List 2");
    Registrar.AddArguments('Base64String', ParameterType::Text);
    Registrar.RegisterMethod('Base64Encode', 'Encodes a string to a base64 value', ReturnType::Text, NSInvokable::"BIS Function List 2");
    Registrar.AddArguments('StringValue', ParameterType::Text);
  end;
}