D365 Chain of Command Extension and Event Handler Generator
Extending standard D365 Finance and Supply Chain code without overlayering is done through class extensions that wrap methods and through event handlers. This generator creates the skeletons so you can concentrate on the business logic.
Fill in
Used in the extension class name so it stays unique.
Leave empty if the method has no parameters, for example: str _id, int _qty
For methods with a return value use for example: boolean ret = next validate(_id);
1. Class extension with chain of command
[ExtensionOf(classStr(SalesFormLetter))]
final class SalesFormLetter_Contoso_Extension
{
public void run([Parameter list])
{
// Logic before the base method
next run();
// Logic after the base method
}
}2. Table data event handlers
class SalesTable_Contoso_EventHandlers
{
[DataEventHandler(tableStr(SalesTable), DataEventType::Inserting)]
public static void SalesTable_onInserting(Common _sender, DataEventArgs _e)
{
SalesTable rec = _sender as SalesTable;
// Set defaults on the record before it is inserted
}
[DataEventHandler(tableStr(SalesTable), DataEventType::ValidatingWrite)]
public static void SalesTable_onValidatingWrite(Common _sender, DataEventArgs _e)
{
SalesTable rec = _sender as SalesTable;
ValidateEventArgs args = _e as ValidateEventArgs;
// args.parmValidateResult(false) to block the write
}
}3. Table extension wrapping a table method
[ExtensionOf(tableStr(SalesTable))]
final class SalesTable_Contoso_Extension
{
public void insert()
{
// Logic before insert
next insert();
// Logic after insert
}
}Chain of command wrappers must be in a final class and call next. Unless the target method is marked Replaceable or Wrappable, the next call must be unconditional at the top level of the wrapper. Private methods cannot be wrapped, and methods must be public or protected and not static unless the base is static. Check the Microsoft documentation for your release for current rules.
Review your extension strategy
Share your list of planned customizations and we can flag which could be configuration, reports or integration instead.
Optional. The tool and every export work without this. No spam.
How to use it
Enter the class you want to extend, a suffix that identifies your model, and the method signature you want to wrap. Provide the exact next line, including the return assignment if the method returns a value. Copy the block into a new class in your own model. Build, then debug with a breakpoint in the wrapper to confirm the order of execution relative to other extensions.
- Match the modifier, return type and parameters of the base method.
- Name the class ClassName_Suffix_Extension.
- Keep wrappers thin and move logic into helper classes.
Rules of chain of command
The extension class must be marked final and decorated with ExtensionOf. The wrapper method has the same signature as the base method, without the static keyword unless the base is static. The platform requires you to call next, and by default the call must not sit inside a condition. The attribute Replaceable on the base method relaxes this so that the call may be conditional. Methods marked Wrappable false cannot be wrapped at all.
Events versus chain of command
Use a data event handler when you only react to a table event, such as inserting or validating a write. Use chain of command when you need to add logic around a method, change a parameter or return value, or run before and after the base. Both are supported and can coexist, but order between multiple extensions is not guaranteed, so avoid logic that depends on running before another extension.
Common mistakes
Teams frequently wrap too much and create hidden dependencies between models. Others forget that the extension has access to protected members only through the this reference and cannot see private members.
- Forgetting final on the class.
- Putting next inside an if block without Replaceable.
- Writing long business logic inside the wrapper instead of a helper class.
- Using the same class name in two models without a suffix.
Frequently Asked Questions
What is chain of command in D365 F&O?
It is the extension mechanism that lets you wrap a public or protected method of a class, table or form in a final extension class, run your logic before and after, and call next to run the base method and other extensions.
Why do I get an error that next must be called?
The compiler requires wrapper methods to call next unconditionally at the top level, unless the base method is marked Replaceable. Move the call out of the condition, or add logic around the call instead of skipping it.
Can I wrap private methods?
No. Private methods cannot be wrapped. Wrappable methods must be public or protected. If you need access to private logic, consider an event handler, a pre or post event, or raising a request with Microsoft to expose an extensibility point.
Should I use events or chain of command?
Use data events for reacting to table events and delegates for published hooks. Use chain of command when you need to wrap a method and control logic around the base call. Prefer the lightest option that satisfies the requirement.
If you want help planning extensions versus configuration for a D365 project, Netray can review your fit and gap list and suggest where to avoid customization.
Related Tools
D365 F&O X++ Select Statement Generator
Fill in a table, a filter field and a value to produce a while select, a Query API version and a set-based update_recordset in X++.
Microsoft DynamicsD365 F&O Fit Gap Analysis Worksheet
Editable fit gap worksheet that records requirements, responses, effort and cost with running totals.
Microsoft DynamicsD365 F&O Implementation Health Assessment
Ten-question self-assessment of customization load, update discipline, security, data quality and reporting for a D365 F&O environment.
Microsoft DynamicsD365 F&O Inventory Dimensions Reference
Lookup table of the product, storage and tracking inventory dimensions in D365 F&O and the dimension group flags that control them.
More Microsoft Dynamics tools
See all- D365 F&O OData URL Builder
- D365 Data Management Import Worksheet Template
- D365 Batch Job Checklist
- D365 Security Role Design Worksheet
- D365 One Version Update Test Checklist
- D365 Finance and Supply Chain Functional Design Document Template
- D365 Finance and Supply Chain Fit-Gap Analysis Worksheet
- D365 Finance and Supply Chain Data Migration Mapping Worksheet
- D365 Finance and Supply Chain Cutover Plan Template
Keep exploring
Free tools
- D365 Finance and Supply Chain Change Request Form TemplateA change request form for D365 projects and production support with impact on scope, effort, security, data and testing, plus approval lines.
- D365 Finance and Supply Chain Data Migration Mapping WorksheetAn editable source-to-target field mapping sheet with transformation rule, owner and load status for D365 F&O data migration.
- D365 Finance and Supply Chain License Cost CalculatorEstimate monthly, annual and term cost for D365 Finance and Supply Chain users, including attach licenses, team members and discount.
ERP fixes and how-tos
- Dynamics 365 Supply Chain Management API: OData, Custom Services and Data PackagesD365 Supply Chain / F&O APIs explained: OData data entities, custom services, the data management package API, Entra ID authentication and when to use each.
- Dynamics 365 Supply Chain Wave Planning and Inventory JournalsHow wave planning and inventory journals work in Dynamics 365 Supply Chain Management: wave templates, wave steps, work templates, journal names and posting.
- Dynamics 365 Supply Chain Warehouse Only Mode: What It Is and Its LimitsWhat warehouse management only mode is in Dynamics 365 Supply Chain Management, how to enable it, how orders arrive as shipment orders, and its limits.
AI on your ERP
- AI for Dynamics 365 Finance and Supply Chain beyond CopilotAI for D365 Finance and Supply Chain beyond Microsoft Copilot: private LLM grounded on data entities and OData, on-prem-capable via Local Business Data.
- AI for Dynamics 365 Finance and Supply Chain ProcurementAI for Dynamics 365 Finance and Supply Chain procurement: purchase orders, vendor invoices, product receipts and approvals via OData and data lake exports.
Integrations
- How to add Slack to Dynamics 365 Finance and Supply ChainAdd Slack to Dynamics 365 Finance and Supply Chain: events to alerts, slash commands, interactive approvals and safe write-backs through OData and services.
- How to use ChatGPT with Dynamics 365 Finance and Supply ChainUsing ChatGPT with Dynamics 365 Finance and Supply Chain: custom GPT actions over OData, exports versus live access, data controls and when to go private.
Software
- Microsoft Dynamics 365 Finance and Supply ChainDynamics 365 Finance and Supply Chain Management explained for manufacturers: modules, data entities, OData, deployment, strengths, limits and alternatives.
- Dynamics 365 Field ServiceDynamics 365 Field Service handles work orders, resource scheduling and mobile technicians on Microsoft Dataverse. Modules, integrations and alternatives.