Skill: dataverse-plugin-development


Dataverse / Dynamics 365 Plugin Development

Use this skill when creating, reviewing, or refactoring Microsoft Dynamics 365 / Dataverse plugins in C# using Microsoft.Xrm.Sdk.IPlugin.

Core pattern

  1. Prefer a reusable PluginBase : IPlugin that owns the Dataverse entry point Execute(IServiceProvider).
  2. Put business logic in an override such as ExecutePlugin(LocalPluginContext context).
  3. Use a per-execution LocalPluginContext to expose strongly typed SDK services:
  4. IPluginExecutionContext
  5. IOrganizationServiceFactory
  6. ITracingService
  7. user-scoped IOrganizationService
  8. admin/SYSTEM IOrganizationService only when genuinely needed
  9. Keep plugin classes stateless. Dataverse can cache and reuse plugin instances across executions/threads.
  10. Wrap unexpected errors into InvalidPluginExecutionException; let intentional InvalidPluginExecutionException pass through unchanged.
  11. Trace technical detail; put user-facing messages in InvalidPluginExecutionException.

Validation helpers to include

Good base classes should provide helpers for:

Registration conventions

Common stage constants:

Use PreOperation when modifying the incoming Target so changes are persisted in the same transaction without an extra Update call.

Use images intentionally:

Post Update validation pattern

When validating a required field after Update (for example account.accountnumber):

  1. Remember Target contains only changed attributes, so unchanged values may be absent.
  2. Prefer a registered PostImage alias PostImage with the required attribute.
  3. Fall back to IOrganizationService.Retrieve(entity, id, new ColumnSet(attribute)) if the image is missing.
  4. Throw InvalidPluginExecutionException with the exact business message requested.
  5. Do not add a blanket Depth > 1 early return for pure validators that do not write data; they cannot self-recursively trigger and should still validate updates initiated by other plugins/workflows.
  6. If validation must run on every account update, leave Filtering Attributes empty; filtering on the required field only validates when that field changes.

User-specific workflow note

For Zico, when using Claude for this class of coding task, do not use Claude/Anthropic API. Orchestrate Claude Code through subscription/OAuth only, e.g. wrapper that launches env -u ANTHROPIC_API_KEY claude ..., then verify produced files and publish markdown results to Hermes WWW when requested.

When publishing a markdown result for code artifacts, embed the source code directly in fenced code blocks inside the markdown, not only as links to separate .cs files.

Templates and references

Verification checklist