Coding Standard

Article: Dec 17, 2024

Coding standards are essential to ensure maintainability, scalability, and consistency in any development project. In Dynamics 365 Finance and Operations (D365 FO), adhering to best practices minimizes risks, improves collaboration, and aligns with Microsoft's recommendations for extensibility.

Class Extension Model

Class extensions allow developers to extend the functionality of existing classes without modifying the base code. This approach supports clean separation of custom logic and ensures compatibility with Microsoft updates.

Example: Class Extensions

[ExtensionOf(tableStr(SalesTable))]
final class SalesTable_Extension
{
    public boolean validateWrite()
    {
        // Add custom validation logic
        return next validateWrite();
    }
}

Class extension model in X++ - Microsoft documentation.

Method Wrapping and Chain of Command

Chain of Command (CoC) is a pattern for extending methods without overriding them. It allows multiple extensions to execute their logic in a sequence.

Benefits of CoC

  • Testability refers to the modularity of logic, making it easier to isolate during testing.
  • Maintainability ensures that multiple extensions can coexist without conflicts.

Example: Chain of Command

[ExtensionOf(tableStr(SalesLine))]
final class SalesLine_Extension
{
    public void initFromSalesTable(SalesTable _salesTable)
    {
        // Add custom logic before the base implementation
        super(_salesTable);

        // Add custom logic after the base implementation
    }
}

Class extension - Method wrapping and Chain of Command - Microsoft Documentation.

Naming Guidelines for Extensions

Proper naming conventions are critical for code readability and to minimize conflicts across models. Customer-specific models may vary in number and purpose, but they typically contain extensions and custom features for a single customer. These models should be named thoughtfully, often incorporating the customer's name or a meaningful abbreviation.

General Rules for Naming Models and Prefixes

  • Models can be named based on the customer’s company name or a combination of the company name and a business area abbreviation.
  • Prefixes or infixes derived from the model name should be used consistently in naming elements.
  • For example, a model for a customer "Contoso" with a focus on warehousing might use ConWMS_ as its prefix for all extensions and metadata.

This approach minimizes naming conflicts and encourages clarity. While many organizations already have recommended naming practices, these guidelines aim to inspire new ideas or broaden perspectives.

Naming Extensions

Extensions should align with Microsoft's module naming conventions, ensuring consistency across D365 FO projects. The model name should reflect the customer's business area or module purpose, and this naming should extend to prefixes or infixes for all associated elements. Avoid generic names like <Element>.Extension to reduce the risk of conflicts.

  • Avoid generic names like <Element>.Extension to reduce the risk of conflicts.

Example: Naming Extensions

For a customer "Contoso" with a warehouse management-specific model:

  • A table extension for InventTable in a model named ContosoWMS might be named InventTable.ConWMSExtension. A field added to the SalesTable could be named ConWMSDeliveryDate, where ConWMS reflects the model name abbreviation.

Naming Extension Classes

  • Extension classes must be unique across all types and models.
  • Start the name with the type being extended and end with _Extension.

Example: Naming Extension Classes

For the same customer "Contoso":

  • An extension class for the CustTable table in a model focused on accounts payable might be named CustTable_ConAP_Extension, where ConAP stands for "Contoso Accounts Payable."

Naming Fields, Field Groups, and Other Metadata

Fields, field groups, and other metadata elements should follow the module's naming pattern. Use the model prefix or abbreviation to ensure consistency and avoid conflicts.

  • Ensure clear, descriptive terms to indicate the purpose of the metadata.

Example: Naming Fields and Metadata

For the "Contoso" customer:

  • A field added to the ShipmentLine table in the ContosoWarehouseManagement model might be named ConWMSShipmentTrackingCode to indicate its purpose and alignment with the model's focus on shipment tracking.

Naming Variables and Methods in Extensions

  • Create unique, readable names.
  • Add a prefix, abbreviation, or context-specific term if necessary to avoid conflicts.

Example: Naming Variables and Methods

For the "Contoso" customer:

  • A variable for a local delivery schedule might be named conWMSLocalDeliverySchedule.
  • A method to calculate optimal inventory allocation might be named calculateConWMSInventoryAllocation to reflect its relevance to warehouse operations and its focus on computation.

Naming guidelines for extensions - Microsoft Documentation.

Writing Extensible Code

To ensure extensibility, design your code with the following principles:

  • Avoid hardcoding by using parameters or configuration to manage behavior.
  • Implement design patterns such as Dependency Injection or Strategy Pattern to make your code adaptable.
  • Keep your custom code loosely coupled from base logic to enhance maintainability and flexibility.

Example: Writing Extensible Code

public void assessInventoryStatus(InventoryItem _item)
{
    if (this.isLowStock(_item))
    {
        this.triggerReplenishment(_item);
    }
    else if (this.isOverstocked(_item))
    {
        this.flagForReview(_item);
    }
    else
    {
        this.markAsSufficient(_item);
    }
}

Write extensible code - Microsoft Documentation.