Chain of Command (CoC) in Dynamics 365 Finance & Operations
Question 1 — Extension model, syntax, and why CoC is preferred over event handlers.
Interview Question
Model Answer (Short)
Chain of Command is an extension mechanism in X++ that lets you wrap a logical method of a
standard (or third-party) class, table, form, or data source without over-layering it. You declare an
extension class decorated with the [ExtensionOf(...)] attribute, re-declare the target method with the
same signature, and call next methodName(...) to invoke the original implementation. This keeps
customizations upgrade-safe because Microsoft's base code is never modified — your logic simply executes
before and/or after the standard behaviour.
Detailed Explanation
The extension class
A CoC class must be marked final, use the [ExtensionOf] attribute pointing to the target,
and its name should end with the _Extension suffix. The method you override must match the
exact signature of the base method.
The next keyword
Calling next executes the next implementation in the chain (ultimately the standard method).
Code you write before next runs first; code after next runs once the base
logic completes and can act on its return value.
Prerequisites (Rule 5)
- Visual Studio with the Dynamics 365 developer tools installed.
- A custom model and package with a reference to the package that owns the target object.
- Object must be developed in the appropriate extension layer (never modify Microsoft base code directly).
- Understanding that the target method must be hookable (public/protected and not final).
Code Example — Table method CoC
Adding validation to the validateWrite() method of a standard table using CoC:
[ExtensionOf(tableStr(SalesTable))]
final class SalesTableAbc_Extension
{
public boolean validateWrite()
{
// ---- Pre-logic: runs before the standard validation ----
boolean ret;
// ---- Call the standard implementation ----
ret = next validateWrite();
// ---- Post-logic: runs after the standard validation ----
if (ret && this.CustAccount == '')
{
ret = checkFailed("Customer account cannot be blank.");
}
return ret;
}
}
Form data source CoC (naming pattern)
[ExtensionOf(formDataSourceStr(SalesTable, SalesTable))]
final class SalesTableFrm_SalesTableDS_Abc_Extension
{
public void write()
{
next write(); // run standard write
// custom post-write logic here
}
}
CoC vs. Event Handlers
| Aspect | Chain of Command | Event Handler (Pre/Post) |
|---|---|---|
| Access to logic flow | Full control — run code before and after next |
Only before (Pre) or after (Post) the method |
| Can skip / replace base logic | Yes — you decide whether to call next |
No — base method always runs |
| Access to parameters & return value | Directly, strongly typed | Via XppPrePostArgs (weakly typed) |
| Readability | Cleaner, method-like | More boilerplate |
| Recommended when | Default choice for most customizations | When many hooks on form elements would create too many CoC methods |
Points the interviewer wants to hear
- CoC keeps customizations upgrade-safe — no over-layering of Microsoft code.
- The extension class must be final and use
[ExtensionOf]. - The wrapped method signature must exactly match the base method.
- You must call
nextfor wrappable methods (unless deliberately replacing behaviour where allowed). - Prefer CoC over event handlers unless a form has a large number of hooks.
Likely Follow-up Questions
- Can you use CoC on a
staticmethod? (Yes, if it is hookable.) - What happens if you don't call
nexton a method that returns a value? - Difference between wrapping a method and subscribing to its Pre/Post event?
Key Takeaway
Chain of Command is the modern, upgrade-safe way to customize standard D365 F&O objects.
Master the pre → next → post flow, the [ExtensionOf] attribute, and the
_Extension naming convention, and you can confidently answer most X++ extensibility questions.