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 namedContosoWMS
might be namedInventTable.ConWMSExtension
. A field added to theSalesTable
could be namedConWMSDeliveryDate
, whereConWMS
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 theContosoWarehouseManagement
model might be namedConWMSShipmentTrackingCode
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);
}
}