Dynamics 365 FO - Customize with extensions and overlayering - Part 3 - Microsoft Dynamics 365 Vietnam

Microsoft Dynamics 365 Vietnam

Song Nghia - Microsoft Dynamics 365 Vietnam

Breaking

Saturday, September 17, 2022

Dynamics 365 FO - Customize with extensions and overlayering - Part 3

 Dynamics 365 FO - Customize with extensions and overlayering

Nghia Song -  Microsoft Dynamics 365 Technical Consultant

Nghia Song

Tel - WhatsApp: +84967324794

Email: songnghia.uit@gmail.com


Class extension – Method wrapping and Chain Of Command

The functionality for class extension, or class augmentation, has been improved. You can now wrap logic around methods that are defined in the base class that you're augmenting. You can extend the logic of public and protected methods without having to use event handlers. When you wrap a method, you can also access public and protected methods, and variables of the base class. In this way, you can start transactions and easily manage state variables that are associated with your class.


For example, a model contains the following code.

You can now augment the functionality of the doSomething method inside an extension class by reusing the same method name. An extension class must belong to a package that references the model where the augmented class is defined.


In this example, the wrapper around doSomething and the required use of the next keyword create a Chain of Command (CoC) for the method. CoC is a design pattern where a request is handled by a series of receivers. The pattern supports loose coupling of the sender and the receivers.

Capabilities

    1. Wrapping public and protected methods

Protected or public methods of classes, tables, data entities, or forms can be wrapped by using an extension class. The wrapper method must have the same signature as the base method.


  • When you augment form classes, only root-level methods can be wrapped. You can't wrap methods that are defined in nested classes.

  • Currently, only methods that are defined in regular classes can be wrapped. Methods that are defined in extension classes can't be wrapped by augmenting the extension classes. This capability is planned for a future update.

  1. What about default parameters?

Methods that have default parameters can be wrapped by extension classes. However, the method signature in the wrapper method must not include the default value of the parameter.

For example, the following simple class has a method that has a default parameter.

In this case, the wrapper method must resemble the following example.

  1. Wrapping instance and static methods

Instance and static methods can be wrapped by extension classes. If a static method is the target that will be wrapped, the method in the extension must be qualified by using the static keyword.

For example, we have the following A class.

In this case, the wrapper method must resemble the following example.

Wrapper methods must always call next

Here are some important rules:

  • Calls to next can't be done conditionally inside an if statement.

  • Calls to next can't be done in while, do-while, or for loop statements.

  • A next statement can't be preceded by a return statement.

  • Because logical expressions are optimized, calls to next can't occur in logical expressions. At runtime, the execution of the complete expression isn't guaranteed.

Wrapping a base method in an extension of a derived class

Therefore, there is one base class, A. Two classes, B and C, are derived from A. We will augment or create an extension class of one of the derived classes (in this case, B), as shown here.

Accessing protected members from extension classes

As of Platform update 9, you can access protected members from extension classes. These protected members include fields and methods. Note that this support isn't specific to wrapping methods but applies all the methods in the class extension. Therefore, class extensions are more powerful than they were before.

If a method is explicitly marked as [Hookable(false)], the method can't be wrapped in an extension class. In the following example, any method can't be wrapped in a class that augments AnyClass1.

For compatibility reasons, [Hookable(false)] overrides the behavior of the chain of command in addition to pre- and post-handlers. However, [Hookable(true)] only applies to pre- and post-handlers and does not influence the chain of command wrapping.

Naming guidelines for extensions

    1. Naming model elements

Every element in a model must have a name that is unique across all models at installation time. However, at installation time, you don't know the names of all the models that your model might be installed together with. To accommodate this situation, every element name should include a prefix that is specific to your solution. By including this prefix when you name elements in your model, you significantly reduce the risk of naming conflicts.


If a model contains multiple solutions, each solution in the model can be identified by a different prefix.

You must carefully choose the prefix to minimize the risk that other models from other parties use the same prefix for their elements.

When you extend functionality in other models, elements that are being extended already contain a prefix. However, you should not add your prefix to the extension elements, so that the names include multiple successive prefixes. Instead, you should include your prefix or another term or abbreviation as an infix when you name extension elements.

  1. Naming extensions

An extension element, such as a table extension, view extension, or form extension, must have a unique name that minimizes the risk of conflicts with extensions in other models. To minimize the risk of conflicts, the name should include a term, abbreviation, or infix that distinguishes the extension from other extensions to the same element in other models.

Include either the name of the model where the extension element resides or the prefix that the extension is associated with. For example, a Warehousing module extends the HCMWorker table and uses the WHS prefix in the name of all other elements. In this case, the extension might be named HCMWorker.WHSExtension. Notice that the prefix that is used to name other elements in the module is inserted as an infix in the name. As another example, an extension of the ContactPerson table in the ContosoCustomizations model might be named ContactPerson.ContosoCustomizations if the extension is intended to contain all extensions to the ContactPerson table from the ContosoCustomizations model. The developer tools will default to using the model's name as the extension name, since the model name is already required to be unique.

Don't name the extension just <Element that is being extended>.Extension. For example, an extension of the InventLocation table must not be named InventLocation.Extension, because the risk of conflicts is too high.

  1. Naming extension classes

Extension classes that are used to augment the logic on tables, classes, or other elements must have a name that is unique across all types in all models. Preferably, the extension class should include the name of the type that is being extended. However, the name must also include a term, abbreviation, or prefix that distinguishes the class from other types.

  • Start the name of the extension class with the name of the type that is being augmented, and end the name with the term _Extension. Therefore, an extension class that augments the ContactPerson table should start with the name ContactPerson and end with _Extension. For example, one extension class might be named ContactPersonWHS_Extension.

  • Include either the name of the model where the extension element resides or the prefix that the extension is associated with. For example, a Warehousing module uses an extension class to augment the ContactPerson table and uses the WHS prefix in the name of all other elements. In this case, the extension class might be named ContactPersonWHS_Extension. Notice that the prefix that is used to name other elements in the module is inserted as an infix in the name. As another example, an extension class that augments the ContactPerson table in the ApplicationSuite model might be named ContactPersonApplicationSuite_Extension if the extension class is intended to contain all extensions to the ContactPerson table in the ApplicationSuite model.

  • Consider adding additional element type information in case you create a class extension for elements that can't be declared in the code (like Forms, DataSources, or FormControls). For example, CustTableFormWHS_Extension is the extension for the CustTable form.

  • Don't name the extension just <Element that is being extended>_Extension. For example, an extension class that augments the InventLocation table must not be named InventLocation_Extension, because the risk of conflicts is too high.

  1. Naming fields, field groups, indexes, relations, and metadata elements added in extensions

Fields, field groups, indexes, relations, and metadata elements added in extensions must have a name that is unique across both the element that is being extended and other extension elements. Therefore, these artifacts should include a prefix that minimizes the risk of conflicts across models. In addition, these artifacts should have clear terms and abbreviations so that they can be easily understood.

  • Include a prefix, term, or abbreviation at the beginning of the name of the metadata node. For example, an approving worker foreign key field is added as part of a table extension, and WHS is one of prefixes that are dedicated to other elements in the hosting model. In this case, the field might be named WHSApprovingWorker.

  1. Naming variables and methods added in extension classes 

Variables and methods added in extension classes must have a name that is unique across both the type that is being extended and all other extension classes that extend the same type. You should take care to create unique and readable names for variables and methods. When you can't create a unique name, then you should apply a prefix to minimize the risk of conflicts across models.


  • Create unique and readable names for variables and methods. For example, an approving worker class-level member variable might be named approvingWorkerForLocalWarehouse if the area of functionality is related to supporting some local warehouse extension functionality. An approveWork method for the same area of functionality might be named approveWorkForLocalWarehouse.


  • When you cannot create a unique and readable name, then add a prefix, term, or an abbreviation at the beginning of the member variable or method name. For example, an approving worker class-level member variable might be named whsApprovingWorker if WHS is one of the prefixes that is used by other elements in the model. An approveWork method might be named whsApproveWork if WHS is a prefix that is used by other elements in the hosting model.


  • Avoid generic names, because the risk is high that multiple extensions could be using the same term or that the base functionality would be enhanced with an identical name in a future release. Some example of names likely to collide are Approver, Delay, Group, Lookup, and Process.

Next: Dynamics 365 FO - Customize with extensions and overlayering - Part 4
https://www.songnghia.com/2022/09/dynamics-365-fo-customize-with_22.html

No comments:

Post a Comment