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.

 

Example

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))
    {
        _ret.result("@MyLabelFile:MyClassDescription");
    }
}

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!

 

THIS POST IS PROVIDED AS-IS; AND CONFERS NO RIGHTS.


Comments (0)

Skip to main content