Blogs

How to extend Dynamics 365 without making upgrades painful

Configuration, Power Automate, client scripts, PCF, plugins or Azure? A practical way to choose, and the habits that keep extensions safe through every release wave.

Dynamics 365 rarely fits an organisation perfectly out of the box. Sooner or later someone needs a field that calculates itself, an approval that crosses three teams, or a connection to a finance system. The question is not whether to extend it, but how, so that the platform still upgrades cleanly twice a year and the next person can understand what was built.

This guide sets out the options from lightest to heaviest, how to choose between them, and the habits that keep extensions safe.

Start with configuration

A surprising amount can be done without writing code. Before reaching for a developer, check whether configuration covers it:

  • Tables, columns and relationships to model the data properly, including choice columns and alternate keys.
  • Calculated, rollup and formula columns for values derived from other data.
  • Business rules to show, hide, require or set fields on forms and on the server.
  • Business process flows to guide people through stages such as intake, assessment and decision.
  • Forms, views, charts and dashboards tailored to each role, so people only see what they need.
  • Security roles, teams and field security to control who can see and change what.

Configuration is upgrade-safe, visible to anyone with the right access, and cheap to change. Every step further down this list adds capability, and also cost to build, test and maintain.

The extension ladder

When configuration is not enough, work down this list and stop at the first option that does the job well.

  1. Power Automate. Good for approvals, notifications, scheduled jobs and hand-offs between systems using standard connectors. Flows run asynchronously, so they suit work that does not need to finish before the user sees the result.
  2. Client scripting. JavaScript web resources on forms for behaviour business rules cannot express, such as conditional filtering of lookups or calling a custom API from a button. Use the supported client API (formContext, not the deprecated Xrm.Page) and never manipulate the page directly.
  3. Power Apps component framework (PCF). Custom controls that replace a field or grid with something better suited to the job, such as a map, a timeline or a richer editor. They are packaged in solutions and behave like built-in controls.
  4. Plugins and custom APIs. C# code that runs inside Dataverse when records are created, updated or deleted, or on demand through a custom API. Use them for rules that must always be enforced, whichever app, flow or integration makes the change.
  5. Azure. Azure Functions, Service Bus and Logic Apps for long-running work, heavy processing, or integration with systems outside Microsoft. Dataverse can send events to Service Bus, which keeps the platform responsive while Azure does the work.
  6. A separate application. Power Pages for external portals, or a custom .NET application when the user interface or the transaction volume is beyond what model-driven apps handle well.

Choosing the right tool

A few questions settle most decisions:

  • Must the rule always apply, no matter how the data changes? Use a plugin or a server-side business rule. A form script only runs when someone uses that form.
  • Does the user need the result before they carry on? Use a synchronous plugin or a custom API, and keep it fast. Otherwise, run it asynchronously in a flow, an async plugin or Azure.
  • Does it talk to another system? For a handful of calls, a flow with a connector is fine. For volume, reliability and retries, publish an event to Service Bus and handle it in Azure.
  • Will business users need to change it? Flows and business rules are easier for a trained administrator to adjust than compiled code.
  • How much data does it touch? Anything that loops over thousands of records belongs in Azure or a batch job, not a flow triggered on every save.

Keep every extension upgrade-safe

Microsoft ships two major release waves a year, plus regular updates in between. Extensions that follow the supported model carry through them. Extensions that do not become the reason upgrades are feared.

  • Work in solutions with your own publisher prefix. Never customise the default solution directly.
  • Deploy managed solutions to test and production. Keep unmanaged solutions in development only, and move changes through environments with pipelines rather than by hand.
  • Use only supported techniques. No direct database access, no editing of the page structure, no undocumented APIs. If a technique is not in Microsoft’s documentation, assume it will break.
  • Watch solution layering. Every unmanaged change made directly in production sits on top of your managed solutions and quietly overrides them. Check the solution layers on key components regularly.
  • Keep source code in a repository. Plugins, PCF controls and web resources should be built from source control, not from whichever developer’s laptop last had them.
  • Test against early access. Each release wave can be switched on early in a sandbox. Use it to test your extensions before the update reaches production.

Build for performance from the start

Most slow Dynamics 365 environments were not built slow. They became slow, one reasonable extension at a time. A few habits prevent that:

  • Register plugins narrowly. Use filtering attributes so an update plugin only fires when the columns it cares about change, and use pre-images and post-images instead of retrieving the record again.
  • Keep synchronous plugins short. They run inside the user’s save. Anything slow or external should be asynchronous.
  • Retrieve only the columns you need. Asking for all columns is convenient and expensive.
  • Do not duplicate logic. A plugin and a flow both reacting to the same change is a common cause of double processing and slow saves.
  • Respect service protection limits. Dataverse limits how many requests a user or integration can make in a short period. Batch requests, avoid polling and use events instead.

Document what you build

Each extension should have a short record: what it does, why configuration was not enough, what triggers it, who owns it and how to switch it off. It takes minutes to write and saves days when someone new needs to change it, or when an upgrade behaves unexpectedly.

A quick checklist

  • Could configuration do this?
  • Is this the lightest option on the ladder that does the job well?
  • Does the logic run in exactly one place?
  • Is it in a solution, in source control, and deployed through pipelines?
  • Does it use only supported techniques?
  • Will it still perform with ten times today’s data?
  • Is it written down?

If you are planning an extension, or have inherited a platform full of them, we are happy to talk it through.

Dynamics 365Power PlatformDataverseAzure