Showing posts with label CSharp. Show all posts
Showing posts with label CSharp. Show all posts

Get Started with Dynamics 365 Plugin Development: A Practical Guide

Get Started with Dynamics 365 Plugin Development: A Practical Guide

Get Started with Dynamics 365 Plugin Development: A Practical Guide

Write the plugin, understand every line, register it, and confirm it actually runs.

What a plugin actually is

A plugin is how you run custom C# code the moment something happens in Dynamics 365 — a record created, updated, or deleted.

Plugins run on the server, not inside your own application, so the setup and the debugging look a little different from a normal C# project.

This guide covers everything you need: writing the plugin, understanding what each piece of code does, registering it in D365, and testing it.

Scenario

Trigger: a new Account record is created.

Logic: if the description field is left blank, the plugin fills it in with a note like "Description auto-populated by plugin on {date}".

This is a simple example, but it uses the same pattern you'll use in almost every plugin: read the record, check a value, update it.

Prerequisites

Before you start
  • Visual Studio 2022 (Community edition is fine). During setup, install the ".NET desktop development" workload — that's what gives you the Class Library (.NET Framework) project template.
  • .NET Framework 4.6.2 as the project's target framework. D365 plugins must use .NET Framework, not .NET Core or .NET 5+, or the plugin won't load.
  • NuGet package: Microsoft.CrmSdk.CoreAssemblies — adds the SDK classes used in the code below.
  • Plugin Registration Tool, available as a NuGet package (Microsoft.CrmSdk.XrmTooling.PluginRegistrationTool) or as a tool inside XrmToolBox. You'll use this to upload your plugin to D365.
  • A D365 environment with a user account that has System Administrator (or System Customizer) access, so you can register plugins and view logs.
  • A strong name key (.snk), created in Visual Studio. D365 requires plugin assemblies to be signed.

Step 1: Create the project

  1. Open Visual Studio → Create a new project.
  2. Search for Class Library (.NET Framework) (not the plain "Class Library" template, which uses .NET Core).
  3. Name it AccountPlugins, confirm the target framework is .NET Framework 4.6.2, and create it.
  4. Right-click the project → Manage NuGet PackagesBrowse → search Microsoft.CrmSdk.CoreAssembliesInstall.
  5. Right-click the project → PropertiesSigning tab → check Sign the assemblyNew... → create a .snk file (password optional). This step is required before you can register the plugin later.

Step 2: Write the plugin class

Every plugin implements IPlugin, an interface with one method: Execute. D365 calls this method whenever your registered event happens.

C# · SetDefaultDescription.cs
using System;
using Microsoft.Xrm.Sdk;

namespace AccountPlugins
{
    public class SetDefaultDescription : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            IPluginExecutionContext context =
                (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory =
                (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            tracingService.Trace("Plugin started for message: " + context.MessageName);

            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is Entity account)
            {
                if (!account.Contains("description"))
                {
                    account["description"] = $"Description auto-populated by plugin on {DateTime.Now}";
                    service.Update(account);
                    tracingService.Trace("Description field updated.");
                }
                else
                {
                    tracingService.Trace("Description already had a value, nothing to do.");
                }
            }
        }
    }
}

What each line means

IServiceProvider serviceProvider

D365 passes this into your plugin automatically. Think of it as a toolbox; everything else you need comes out of it using GetService(typeof(...)).

ITracingService

Lets you write log messages. Since plugins run on the server, you can't debug them like a normal app, so these logs are how you check what happened.

IPluginExecutionContext

Tells you what triggered the plugin, like the message name (Create, Update, etc.) and the record itself. context.InputParameters["Target"] is the actual record being created or updated.

IOrganizationServiceFactory

Creates the service you'll use to talk to D365.

IOrganizationService

The object you use to Create, Retrieve, Update, or Delete records. In this plugin, service.Update(account) saves the change.

Account createdCreate message
PostOperationplugin pipeline stage
Execute() runschecks description
service.Update()description populated

Step 3: Build the assembly

Build the project (use the Release configuration). Check that AccountPlugins.dll was created under bin\Release with no errors. If the build fails because of signing, go back and confirm you completed the signing step in Step 1.

Step 4: Register the plugin

Open the Plugin Registration Tool and connect to your D365 environment:

  1. CREATE NEW CONNECTION → enter your environment URL → sign in.
  2. Register menu → Register New Assembly → select AccountPlugins.dll → set Isolation Mode to Sandbox → click Register Selected Plugins.
  3. Right-click the SetDefaultDescription class in the tree → Register New Step.
  4. Fill in the step (see the mock panel below), then click Register New Step to save.
Plugin Registration Tool AccountPlugins.dll SetDefaultDescription
Register
View
Help
Register
Actions
Debug
Register New Step — SetDefaultDescription Not Registered
Create
account
PostOperation
Synchronous

Click "Register New Step" above to see how the tool confirms the step was saved.

Step 5: Verify it works

Create a new Account record without filling in the Description field, then save it. Reopen the record and check the Description field — it should now show the auto-generated note.

If it doesn't work

Open the Plugin Registration Tool, right-click your step, and use Profile to see the trace log and find out where it stopped.

The rule of thumb

Every plugin follows the same shape: pull the target record out of InputParameters, check a value, and use IOrganizationService to act on it. Once this pattern is comfortable, moving from a simple field default to more complex business logic is mostly a matter of what you check and what you do next — not how the plugin is wired together.