Dataverse plugin template: context, service and Target
Every plugin starts the same way. You need the context, the tracing service, the organization service and the record that fired the plugin (Target). This is the boilerplate I always copy:
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var service = factory.CreateOrganizationService(context.UserId);
if (!context.InputParameters.Contains("Target") || !(context.InputParameters["Target"] is Entity target))
return;
tracing.Trace("Plugin executed on {0} {1}", target.LogicalName, target.Id);
// Your logic here
}CreateOrganizationService(context.UserId) gives you a service with the permissions of the user who triggered the action. Pass null and it runs as SYSTEM, bypassing security, which I only do when there’s really no other way.
The type check on Target is there for a reason too. On a Delete you get an EntityReference rather than an Entity, so casting it straight to Entity would make the plugin fail.
Finally, on an Update the Target only contains the columns that changed. If you need to read others, register a pre-image on the step.