Implement Chain of Command

Completed

Chain of Command (CoC) is a functionality for class extensions. You can use CoC to wrap X++ code around methods that are defined in the base class. CoC allows you to customize standard classes without using event handlers. This function allows you to add custom logic that will run before and/or after the standard code runs. You can only extend the logic of public and protected methods. When you wrap a method, you can also access the base class's protected methods, public methods, and variables. It is important to understand this concept, as base code cannot be changed in Dynamics 365 finance and operations apps development.

To use CoC, you need to create a new class that uses the same name as the class that you are extending with _Extension added to the name as a suffix. The class declaration also needs to use the final keyword to indicate that it cannot be further inherited from. Finally, the ExtensionOf attribute must be used when you are declaring the class. You can then reuse the same method declaration from the base class in the extended class. Inside the extended method, you can add your custom code. You are required to use the next keyword to create a CoC. The next command will call the next method in the Chain of Command. When no more methods exist in the chain, the original (in other words, extended) method is called.

Example

The following code example shows how the class must be declared to use CoC. When the ExampleClass.doSomething() method is called, the code will first run all the code before the next keyword. Then, the original code in the ExampleClass.doSomething() method will run. Finally, all code after the next keyword will run.

[ExtensionOf(classStr(ExampleClass))]
final class ExampleClass_Extension
{
   str doSomething(int arg)
   {
     // Custom logic before standard code.
     var s = next doSomething(arg);
     // Custom logic after standard code.
     return s;
   }
}

Certain methods cannot be wrapped by using CoC. If the method uses a hookable attribute that is set to false, [Hookable(false)], or a wrappable attribute that is set to false, [Wrappable(false)], the method cannot be wrapped. Methods that use the final keyword cannot be wrapped in an extension class. Private methods are also excluded from extensibility.