Custom Macro Functions
Custom macro functions are implemented centrally in a common interface library. The path of this interface library is specified in the global configuration property General.CustomMacrosAssemblyPath. In contrast to the names of the classes for custom modules, with custom macro functions the names of the classes are fixed, with one class for each type of macro function in which all the relevant methods are to be implemented:
CustomFieldMacros: field macro functionsCustomDocumentMacros: document macro functionsCustomFileMacros: file macro functionsCustomGlobalMacros: global macro functions
Select the names of the methods as needed, but – just like the classes – always declare them as public and static, and ensure that the names do not collide with those of internal macro functions. Also, ensure that the methods have a specific signature depending on their type, defined in the form of a delegate in the XSuite.Interface.CustomModules.Macros namespace of the CustomModules.dll file. Common to all of them as call parameters is 1) a list of custom parameters for precisely this macro function, 2) a list of all document/system/environment variables available in the respective context, and 3) a logging component.
Delegate | Description |
|---|---|
object CustomFieldMacroFunction( IList<object> customParams, Document document, IDictionary<string, object> variables, ICustomLogger logger) | A field macro function receives the entire document object as a specific call parameter (e.g., in order to be able to access (read) field contents that are not transferred as custom parameters). Only the return value is accepted as the result of the function execution; any changes made directly to the document are ignored. This value must correspond to a .NET data type supported by the macro interpreter – or at least be convertible to it: |
void CustomDocumentMacroFunction( IList<object> customParams, Document document, IDictionary<string, object> variables, ICustomLogger logger) | A document macro function has the same signature as a field macro. However, a document macro function does not have a return value; the modifications must be made directly to the transferred document object. All changes to existing field contents are applied; however, new fields may only be added in the context of table fields by inserting new lines. Such a line does not necessarily have to include all declared fields, as the missing ones are added by the program and assigned their initial values. Newly set field values must correspond to a .NET data type supported by the macro interpreter – or, as a minimum, be convertible to this data type. In addition to field changes, changes to the metadata and external keys of the document and its file attachments are also applied. |
IList<Attachment> CustomFileMacroFunction( IList<object> customParams, List<Attachment> filteredAttachments, Dictionary<string, object> variables, CustomLogger logger) | A file macro function receives as specific call parameters those file attachments that are to be used as source files for the macro execution according to the file name filter (first standard parameter of each file macro). In contrast to internal file macros, no distinction is made as to whether the macro expects one or more input files in order to be called multiple times with one file each or only once with all files. For internal file macros, the latter type of call always takes place, for which reason individual file processing may have to be taken into account in its own processing logic. All files that the macro returns as a function result are adopted and added to the document as new file attachments. The file names supplied serve as the basis for creating the target file names according to the defined pattern (second standard parameter with default value In the context of a file macro, the binary data of the file attachments are always transferred as streams in the |
void CustomGlobalMacroFunction( IList<object> customParams, Dictionary<string, object> variables, CustomLogger logger) | A global macro function has no specific call parameters, as there is no processing context for a batch or a document and, as a global macro function, it can be used for a variety of purposes. Direct access to internal resources such as storage or the administrative database is currently not provided for external macros; this can at best be achieved by establishing an independent connection to the resource. |
In a macro expression, the custom functions are called in the same way as the internal functions, namely directly via their name (just like the relevant method has been named in the class library), and with their custom parameters. This parameter list varies in length, and its values are passed to the custom method that implements the macro function, with the macro function bundled in the customParams call parameter. As the internal macro interpreter does not support named parameters, they can only be identified by their their place in the sequence.
Internal macro functions have a general option for checking data type and mandatory fields. This option is also made available to the external functions, basically ensuring that the transferred values meet the requirements of your custom macros, without requiring you to implement the checks completely yourself. However, the transfer is made as a general object type, for which reason at least one cast to the specific target type will be necessary in your own code. In the XSuite.Interface.CustomModules.Macros namespace of CustomModules.dll, three special attributes are defined with which the custom methods can be labeled, as follows:
CustomParamsTypeAttribute: Data type of the parameter, e.g.typeof(string)(default value), attempt to convert if necessaryCustomParamsRequiredAttribute: Mandatory field,trueorfalse(default value)CustomParamsDefaultAttribute: Default value if parameter value is missing
The attributes each accept a variable number of values that correspond to the custom macro parameters in their order. For example, if a macro expects three parameters of the types string, string, and bool, the following attribute must be specified:
[CustomParamsType(typeof(string), typeof(string), typeof(bool))]
The data types that are permitted for the type check and for default values are those that are supported by the internal macro interpreter or which can be converted implicitly: string (text value), double (numerical value), bool (Boolean value), System.DateTime (date value), and System.Array. The type long can also be used for integer values in this context. When checking the type of enumeration values, in general only the array type can be checked, but not the type of the elements contained.
In addition to the three attributes above, the RequiresFileStreamsAttribute attribute, which accepts a single Boolean value, is available. It is only relevant for field and document macro functions where this value is used to determine whether the streams of the contained file attachments are also to be loaded into the document object transferred to them. As most macros do not require access to the binary data of these files, the default value is false so as not to occupy memory unnecessarily.
Custom macro functions are also displayed in the configurator's macro editor dialog. In order to display not just their name, but also a description and information on parameters and return value, similar to the internal macros, XML comments set in your own program code are evaluated for the relevant methods, specifically the standard tags <summary>, <param>, and <returns>. If you want to prevent misuse of <param>, use the non-standard tag <customparam>, which has the same syntax except for the name, instead. Strictly speaking, <params> refers to all parameters in the method implementing the macro function and not to the individual values within the customParams list. In order to gain access to the XML comments in the first place, xSuite Interface requires a corresponding XML documentation file. This XML documentation file must be generated for its own class library and located under the same base name as the .dll library file, in the same directory as the latter. This generation can be activated directly in the project file of the class library, as in this example:
<PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup>
The following example shows the use of XML comments and attributes for a field macro function. Two custom parameters of the types long and bool are expected (CustomParamsTypeattribute). The first parameter (attribute CustomParamsRequired) is mandatory. This information is missing for the second, so that false is implicitly valid. The second parameter has the default value true (attribute CustomParamsDefault). The value null for the first parameter means that no default value is defined. The first parameter is a mandatory parameter and is only specified as a placeholder in order to maintain the correct sequence.
public static class CustomFieldMacros
{
/// <summary>Custom field macro sample.</summary>
/// <customparam name="param1">first parameter</customparam>
/// <customparam name="param2">second parameter</customparam>
/// <returns>The result value.</returns>
[CustomParamsType(typeof(long),
typeof(bool))]
[CustomParamsRequired(true)]
[CustomParamsDefault(null, true)]
public static object
CustomFieldMacroSample(
IList<object> customParams,
Document document,
IDictionary<string, object>
variables,
ICustomLogger logger)
{
throw new NotImplementedException();
}
}