Assess the extensibility of code

Completed

When you customize finance and operations apps, your changes need to be stable, safe, and upgradeable. Extensibility features help you modify behavior without disrupting Microsoft's core application code. When extensibility best practices aren't followed, or when intrusive customizations are used, the result can be breaking changes that prevent updates, cause unpredictable behavior, or reduce system reliability. In this unit, you'll learn how to assess code for extensibility, recognize unsafe patterns, and identify situations where customizations may introduce breaking changes.

Understand extensibility in finance and operations apps

Finance and operations apps use a structured extensibility model that allows developers to add or modify behavior without altering the base application code. This model supports long-term maintainability by ensuring your customizations survive updates.

When assessing code for extensibility, consider the following:

  • How the application exposes extension points: Classes, tables, and methods often include extensibility attributes that indicate whether they can be safely extended. Understanding these attributes helps you identify where you can plug in custom behavior.

  • Why extensibility matters: Proper extensibility protects standard logic during updates, reduces merge conflicts, and supports predictable behavior across environments.

  • Which extension mechanisms are available: Developers can use event handlers, delegates, extension classes, chain-of-command patterns, and metadata extensibility. Each method has rules about how it can be used and how it affects execution.

Note

The Microsoft guidance on "writing extensible code" explains how to follow these patterns and how to recognize when elements are designed for safe extension.

Identify and assess potential breaking changes

Breaking changes occur when a customization alters the behavior or structure of the base application in ways that downstream code or future updates cannot handle. Assessing a codebase for these risks is a critical developer responsibility.

Key areas to analyze include:

Method signatures:

  • Changing parameters, return types, or access modifiers can break dependent code and prevent compilation after updates.

  • Changed method signature from ISV solutions might result in runtime errors and should be avoided.

Chain of Command implementation:

When assessing CoC extensions, look for these common pitfalls that break the system:

  • Not calling next(): Breaks continuation of business logic, skipping validation or security checks

  • Changing method signatures: Alters return types or parameters, causing runtime errors in dependent code

  • Introducing unhandled exceptions: Throws exceptions that terminate entire business processes and transactions

  • Creating circular dependencies: Multiple CoC extensions that reference each other cause stack overflow errors or infinite loops

  • Performance issues: Adding expensive operations (complex queries, external API calls) in high-frequency methods dramatically slows down the system

Important

Always call next() in your CoC implementation unless you have a specific business reason to block the chain. Document any such decisions thoroughly.

Note

Methods attributes (hookable, wrappable and replaceable) can be used to control extensibility capabilities.

Execution flow:

  • Extensions that assume a specific execution order may fail when updates introduce new logic.

Class or table contracts:

  • Removing fields, renaming elements, or overriding logic in unsupported ways can cause regression bugs or runtime errors.

  • Extending extended data types needs to be handled with care, because modifying length on a string can affect multiple tables and cause database synchronization.

Upgrade compatibility:

  • Extensibility is designed to be forward-compatible. If your code requires merging or overlayering with Microsoft code, it is at high risk of breaking during updates.

Note

Microsoft's "breaking changes" guidelines outline patterns that are known to cause instability and should be flagged during your assessment.

Evaluate intrusive customizations and their risks

Intrusive customizations modify the base application directly, usually by overlayering, which bypasses the extensibility framework. These approaches should be avoided whenever possible.

When assessing code, look for these specific intrusive patterns:

Direct modifications to Microsoft objects:

  • Direct table modifications: Adding fields directly to standard tables instead of using table extensions can cause merge conflicts and data integrity issues during upgrades. Not supported. Use the SysExtensionSerializer framework for adding fields to standard tables.

  • Overlayering core classes: Modifying standard class code directly prevents receiving Microsoft updates and bug fixes for those components. Not supported.

  • Hardcoding business logic: Embedding business rules directly into forms or data methods instead of using proper separation of concerns makes the code difficult to test and maintain

  • Bypassing security frameworks: Creating custom data access patterns that circumvent record-level security or data policies can expose sensitive information

  • Modifying kernel methods: Attempting to change system-level functionality can destabilize the entire application and void support agreements

Unsupported overrides:

  • If logic replaces core behavior instead of extending it, updates may overwrite or break the customization.

Missing extension points:

  • If code was customized before extensibility features existed, you may need to refactor it into modern extension patterns.

Consequences of intrusive customizations include:

  • Update failures: Intrusive customizations often prevent successful application of service updates and hotfixes, leaving systems vulnerable to security risks

  • Performance degradation: Poorly designed extensions can introduce memory leaks, inefficient queries, or unnecessary database round-trips

  • Data corruption: Customizations that bypass validation logic or transaction boundaries can lead to inconsistent data states

  • Support complications: Microsoft support may be unable to assist with issues stemming from intrusive customizations, requiring expensive remediation

  • Technical debt accumulation: Quick fixes that violate extensibility principles create long-term maintenance burdens and increase the cost of future enhancements

Warning

Intrusive customizations can break during platform updates, causing system downtime and requiring emergency fixes. Always use extensions and extensibility patterns provided by the framework.

Note

Microsoft's documentation on intrusive customizations provides examples and explains why they lead to poor system health.

Assess code against extensibility best practices

When reviewing code for extensibility, evaluate whether it follows established principles that support maintainability and upgradeability.

Key principles to assess:

SOLID principles:

  • Single Responsibility: Classes that handle multiple concerns become difficult to test, modify, and reuse. A single bug fix might inadvertently break unrelated functionality

  • Open/Closed: Modifying existing code instead of extending it increases regression risk and makes parallel development by multiple teams nearly impossible

  • Dependency: Tight coupling between components prevents unit testing, makes code brittle to changes, and complicates dependency management

Clean code practices:

  • Avoid poor naming: Unclear method and variable names force developers to read implementation details, slowing down development and increasing bug introduction rates

  • Use good methods: Methods with dozens of parameters or hundreds of lines become unmaintainable and create bottlenecks for team collaboration

  • Ensure documentation: Undocumented extension points and business rules lead to duplicate implementations and inconsistent behavior across the application

DRY (Don't Repeat Yourself) principle:

  • Duplicate logic: Copying code instead of creating reusable components leads to inconsistent behavior when only some instances are updated. Microsoft often marks new code as internal, and this cannot be extended. In these cases, always try to make workarounds with extensions before duplicating code.

  • Maintenance overhead: Bug fixes must be applied multiple times, increasing the chance of oversight and creating subtle differences in behavior

  • Testing complexity: Redundant code requires redundant tests, expanding test suites unnecessarily and slowing down continuous integration

Real-world consequences of ignoring best practices:

  • Development velocity decreases as technical debt accumulates

  • Bug fix time increases exponentially as the codebase becomes more entangled

  • Onboarding new developers takes longer due to code complexity

  • System stability degrades as untested edge cases multiply

  • Business agility suffers when simple changes require extensive refactoring

Tip

Follow naming conventions and document all extensions to improve collaboration and maintainability. Synchronize the database for all models without deploying new changes using the "Synchronize database" option in Dynamics 365.