Responding through delegates

One typical extension point is when extensible logic is delegating the responsibility of a certain operation, and is expecting extensions to provide a result. It could be a conversion, a calculation, class construction or similar.


Let's look at the pattern, and how to be a good-citizen.



The Batch table has a few delegates, one of them is classDescriptionDelegate.

The delegate's signature is:

delegate void classDescriptionDelegate(Batch _batch, EventHandlerResult _ret)

The EventHandlerResults enables subscribers to return a class description for a given Batch record. A good-citizen would do something like this:

[SubscribesTo(tableStr(Batch), delegateStr(Batch, classDescriptionDelegate))]
public static void MyBatch_classDescriptionDelegate(Batch _batch, EventHandlerResult _ret)
    if (_batch.ClassNumber == classNum(MyClass))

To be a good-citizen it is important to only provide a result when it is related to your extension.

A bully would set the result unconditionally, and thus overwrite other extensions. The order event handlers are invoked is arbitrary – so with two bullies you'd get arbitrary results.

The pattern

You can recognize events expecting a result:

  • Their name is postFixed with "Delegate", as in "I'm delegating the responsibility of …"
  • They have a parameter that allows returning a value, for example, EventHandlerResult. Usually this is the last parameter.
  • XML documentation should describe how to use the delegate – when not, "Find references" and a bit of reverse engineering is your friend.

The delegating code will typically look like this:

delegate myOperationDelegate(<input parameters>, EventHandlerResult _result)
public <result> myOperation()
    EventHandlerResult ret = new EventHandlerResult();    
    this.myOperationDelegate(<input parameters>, ret);
    if (ret.hasResult())
        return ret.result();
    throw error(...);


Please follow this pattern when implementing extensible code – remember others might be extending your solution!



Comments (0)

Skip to main content