All posts

Extending SalesLine with Chain of Command

Sample post. Written to test the site. Replace or delete it before launch.

Overlayering is gone. To change standard behaviour in D365 F&O you write an extension, and for methods that means Chain of Command (CoC).

The shape of a CoC class

An extension class is final, carries the ExtensionOf attribute, and its name ends in _Extension. Each wrapped method has the same signature as the original and must call next.

SalesLine_Contoso_Extension.xpp
[ExtensionOf(tableStr(SalesLine))]
final class SalesLine_Contoso_Extension
{
    public void initFromSalesTable(SalesTable _salesTable)
    {
        // Runs before the standard logic.
        next initFromSalesTable(_salesTable);

        // Runs after it: the standard fields are already set here.
        this.ContosoPriority = _salesTable.ContosoPriority;
    }
}

Rules worth remembering

next is not optional

Forgetting next, or calling it inside an if, is a compile error. The compiler protects the standard logic for you.

  • next must be called unconditionally, not inside an if. Methods marked [Replaceable] are the exception.
  • You can only wrap public and protected methods. private ones are off limits.
  • Put a prefix (here Contoso) in both the class name and new fields, so two models never clash.

When CoC is the wrong tool

If you only need to react to a record being inserted or updated, a data event handler (onInserted, onUpdated) is often simpler and touches less code.

Where does my extension run during an import?

Data entities can skip table methods entirely. See set-based processing in Three things to check in the staging table first.