A plugin is custom .NET code that runs on the Dataverse server itself, triggered by a specific event (a record being created, updated, deleted, or a specific message being called) — and unlike a form script, it runs no matter how that event happened: through a form, the Web API, a data import, a Power Automate flow, or another plugin.

Why “can’t be bypassed” is the whole point

This is the property that makes plugins the right tool for genuine business rules that must always hold — validating data, enforcing relationships, calculating values — anywhere that “someone updated this through the API and skipped the form” would otherwise create bad data. Everything else covered earlier in this learning path (business rules, form scripts, workflows) can, in one way or another, be bypassed by a different entry point. Plugins are the layer that can’t.

What a plugin technically is

A plugin is a class implementing the IPlugin interface, compiled into a .NET assembly, registered against a specific table, message (Create, Update, Delete, etc.), and pipeline stage. Dataverse loads and executes it server-side whenever that registered event fires.

What plugins are good for

  • Data validation that must always be enforced, regardless of entry point
  • Complex calculations too intricate for a Calculated column
  • Cross-record automation that needs to happen synchronously, as part of the same transaction
  • Integration logic calling external systems in response to Dataverse events
What plugins are not for. Long-running processes, heavy external API calls that could time out, or anything that doesn’t need to be tightly coupled to the triggering transaction. Dataverse enforces execution time limits on plugins (synchronous plugins especially), and a slow plugin can visibly degrade the save/update experience for every user who triggers it. For slower or more complex integration work, Power Automate or an async plugin step is usually the better fit — covered in the next chapter.