Register a plug-in
Unsure about entity vs. table? See Developers: Understand terminology in Microsoft Dataverse.
You can use Power Platform Tools for Visual Studio to quickly create and deploy (register) plug-ins. A quickstart article is available to show you how.
A more manual process of writing, registering, and debugging a plug-in is:
- Create a .NET Framework class library project in Visual Studio
- Add the
Microsoft.CrmSdk.CoreAssembliesNuGet package to the project
- Implement the IPlugin interface on classes that will be registered as steps.
- Add your code to the Execute method required by the interface
- Get references to services you need
- Add your custom business logic
- Sign & build the assembly
- Test the assembly
- Register the assembly in a test environment
- Add your registered assembly and steps to an unmanaged solution
- Test the behavior of the assembly
- Verify expected trace logs are written
- Debug the assembly as needed
This topic describes how to register a plug-in assembly and step, and add them to a solution. Additional information can be found in these tutorials:
Plug-in Registration tool (PRT)
You'll use the Plug-in Registration tool (PRT) to register your plug-in assemblies and steps.
PRT is one of the tools available for download from NuGet. Follow the instructions in Dataverse development tools. That topic includes instructions to use a PowerShell script to download the latest tools from NuGet.
Register an assembly
You will find options related to the isolation mode and location for the assembly. These refer to options that apply to on-premise deployments. Dataverse is not available for on-premises deployments, so you will always accept the default options of SandBox and Database for these options.
When an assembly is uploaded, it's stored in the
PluginAssembly table. Most of the properties are set using reflection of the imported table. The base64 encoded bytes of the assembly are stored in the
Content column. While viewing the Properties of the assembly in the PRT, you can only edit the Description value.
View registered assemblies
You can view information about registered assemblies in the application solution explorer without using the PRT.
Navigate to an unmanaged solution
From the Power Apps portal select Solutions, and then on the toolbar, select Switch to classic.
In the All Solutions list select the unmanaged solution you want.
Each assembly you add using PRT will be added to the system Default Solution, (not to be confused with the Common Data Services Default Solution). To view the Default Solution, select All solutions under Solutions and then change the view to All Solutions - Internal.
For more information about solutions, see Introduction to solutions
After selecting the name of the Default Solution in the internal solution list, you can find all the assemblies that are registered for this environment.
Query registered assemblies with code
To view information about registered assemblies without the PRT or the application, use the following Web API query in your browser:
[org uri]]/api/data/v9.0/pluginassemblies ?$filter=ishidden/Value eq false &$select= createdon, culture, customizationlevel, description, isolationmode, major, minor, modifiedon, name, pluginassemblyid, publickeytoken, version
Or use following FetchXml to retrieve it in a program you write:
<fetch> <entity name='pluginassembly' > <attribute name='createdon' /> <attribute name='culture' /> <attribute name='customizationlevel' /> <attribute name='description' /> <attribute name='isolationmode' /> <attribute name='major' /> <attribute name='minor' /> <attribute name='modifiedon' /> <attribute name='name' /> <attribute name='pluginassemblyid' /> <attribute name='publickeytoken' /> <attribute name='version' /> <filter type='and' > <filter> <condition attribute='ishidden' operator='eq' value='false' /> </filter> </filter> </entity> </fetch>
More information: Use FetchXML with FetchExpression
Add your assembly to a solution
As described in View registered assemblies, the assembly registration you created was added to the system Default Solution. You should add your assembly to an unmanaged solution so you can distribute it to other organizations.
Within the unmanaged solution you're using, use solution explorer to navigate to Plug-in Assemblies. In the list menu, select Add Existing. In the following figures, a custom solution named Common Data Service Default Solution is used.
Then add your assembly as a component to the solution.
When you select the plug-in assembly you added, you can view the plug-in classes it includes.
Any existing or subsequent step registrations are not added to the unmanaged solution that includes the plug-in assemblies. You must add each registered step to the solution separately. More information: Add step to solution
Register plug-in step
When an assembly is loaded or updated, any classes that implement IPlugin will be available in the PRT. Use the instructions in Register a new step in the Tutorial: Write and register a plug-in to create a new step registration.
When you register a step, there are many options available to you, which depend on the stage of the event pipeline and the nature of the operation you'll register your code to respond to.
General Configuration Information Fields
|Message||PRT will auto-complete available message names in the system. More information: Use messages with the Organization service|
|Primary Entity||PRT will auto-complete valid tables that apply to the selected message. These messages have a
If you leave it blank for core table messages like
|Secondary Entity||This field remains for backward compatibility for deprecated messages that accepted an array of EntityReference as the
|Filtering Attributes||With the
|Event Handler||This value will be populated based on the name of the assembly and the plug-in class.|
|Step Name||The name of the step. A value is pre-populated based on the configuration of the step, but this value can be overridden.|
|Run in User's Context||Provides options for applying impersonation for the step. The default value is Calling User. If the calling user doesn't have privileges to perform operations in the step, you may need to set this to a user who has these privileges. More information: Impersonate a user|
|Execution Order||Multiple steps can be registered for the same stage of the same message. The number in this field determines the order in which they'll be applied from lowest to highest.
Note: You should set this to control the order in which plug-ins are applied in the stage. It not recommended to simply accept the default value. The actual execution order of the plugins with the same Execution Order value (for the same stage, table and message) isn't guaranteed and can be random.
|Description||A description for step. This value is pre-populated but can be overwritten.|
Event Pipeline Stage of execution
Choose the stage in the event pipeline that best suites the purpose for your plug-in.
|PreValidation||For the initial operation, this stage will occur before the main system operation.
This provides an opportunity to include logic to cancel the operation before the database transaction.
Subsequent operations triggered by extensions registered in other stages will pass through this stage as well but will be included within the transaction of the calling extensions.
This stage occurs before any security checks are preformed to verify that the calling or logged-on user has the correct permission to perform the intended operation.
|PreOperation||Occurs before the main system operation and within the database transaction.
If you want to change any values for an entity included in the message, you should do it here.
Avoid cancelling an operation here. Canceling will trigger a rollback of the transaction and have significant performance impact.
|PostOperation||Occurs after the main system operation and within the database transaction.
Use this stage to modify any properties of the message before it is returned to the caller.
Avoid applying changes to an entity included in the message because this will trigger a new Update event.
Within the PostOperation stage you can register steps to use the asynchronous execution mode. These steps will run outside of the database transaction using the asynchronous service.
More information Asynchronous service.
More information: Event execution pipeline
There are two modes of execution asynchronous, and synchronous.
|Asynchronous||The execution context and the definition of the business logic to apply is moved to system job, which will execute after the operation completes.|
|Synchronous||Plug-ins execute immediately according to the stage of execution and execution order. The entire operation will wait until they complete.|
Asynchronous plug-ins can only be registered for the PostOperation stage. For more information about how system jobs work, see Asynchronous service
Special step registration scenarios
There are certain scenarios where a step registration and table combination isn't obvious. This is the result of how the system is designed internally where there's a special relationship between tables or operations. The information below identifies these cases and provides step registration guidance.
- There are certain cases where plug-ins registered for the Update event can be called twice. More information: Behavior of specialized update operations
- Register a plug-in step on account or contact when you want to handle data changes to customeraddress, leadaddress, publisheraddress, or competitoraddress records.
|Server||The plug-in will run on the Dataverse server.|
|Offline||The plug-in will run within the Dynamics 365 for Outlook client when the user is in offline mode.|
Set configuration data
The Unsecure Configuration and Secure Configuration fields in the PRT allow you to specify configuration data to pass to the plug-in for a specific step.
Secure Configuration data is not included with the step registration when you export a solution.
You can write your plug-in to accept string values in the constructor to use this data to control how the plug-in should work for the step. More information: Pass configuration data to your plug-in
Define entity images
Within your plug-in, you may want to reference primary table property values that weren't included in an operation. For example, in an
Update operation you might want to know what a value was before it was changed, but the execution context doesn't provide this information, it only includes the changed value.
If your plug-in step is registered in the PreValidation or PreOperation stages of the execution pipeline, you could use the Organization service to retrieve the current value of the property, but this isn't a good practice for performance. A better practice is to define a pre-entity image with your plug-in step registration. This will capture a 'snapshot' of the table with the fields you're interested in as they existed before the operation that you can use to compare with the changed values.
The default behavior when creating an entity image is to select all columns. However, this can result in reduced web service performance. Developers should only include those columns that are required.
Messages that support entity images
In Dataverse, only the following messages support entity images:
|Message||Request Class Property||Description|
||The assigned table.|
||The created table.|
||The deleted table.|
||The delivered email ID.|
||The delivered email ID.|
||The parent table, into which the data from the child table is being merged or the child table that is being merged into the parent table.|
||The item being routed.|
||The item being sent.|
||The table for which the state is set.|
||The updated table.|
Types of entity images
There are two types of entity images: Pre Image and Post Image. When you configure them, these images will be available within the execution context as PreEntityImages and PostEntityImages properties respectively. As the names suggest, these snapshots represent what the table looks like before the operation and after the operation. When you configure an entity image, you'll define a table alias* value that will be the key value you'll use to access a specific entity image from the
Availability of images
When you configure an entity image, it's important that you recognize that the type of entity images available depend on the stage of the registered step and the type of operation. For example:
- You can't have a Pre Image for the
Createmessage because the table doesn't exist yet.
- You can't have a Post Image for the
Deletemessage because the table won't exist anymore.
- You can only have a Post Image for steps registered in the PostOperation stage of the execution pipeline because there's no way to know what the table properties will be until the transaction is completed.
- For an
Updateoperation that is registered in the PostOperation stage you can have both a Pre Image AND a Post Image.
Add an entity image
Add step to solution
As mentioned in Add your assembly to a solution, Plug-in Assemblies are solution components that can be added to an unmanaged solution. Sdk Message Processing Steps are also solution components and must also be added to an unmanaged solution in order to be distributed.
The procedure to add a step to a solution is similar to adding an assembly. You'll use the Add Existing command to move it into the desired unmanaged solution. The only difference is that if you attempt to add a step but haven't already added the assembly that contains the class used in the step, you'll be prompted to add missing required components.
If you encounter this, you should usually select OK to bring the assembly in with the unmanaged solution. The only time you wouldn't select this is if your solution is designed to be installed in an environment where another solution containing the assembly is already installed.
Similarly, you should note that removing the assembly from the solution won't remove any steps that depend on it.
Update an assembly
When you change and rebuild an assembly that you've previously registered, you'll need to update it. See the Update the plug-in assembly registration step in the Tutorial: Update a plug-in for the steps.
If you're making changes to a plug-in assembly that is part of a managed solution that has been deployed you need to consider the impact your changes may have when you update that managed solution. The version of the assembly will control the behavior.
Plug-in assemblies can be versioned using a semantic versioning format of
major.minor.build.revision defined in the
Assembly.info file of the Microsoft Visual Studio project. Depending on what part of the assembly version number is changed in a newer solution, the following behavior applies when an existing solution is updated through import.
The build or revision assembly version number is changed
This is considered an in-place upgrade. The older version of the assembly is removed when the solution containing the updated assembly is imported. Any pre-existing steps from the older solution are automatically changed to refer to the newer version of the assembly.
The major or minor assembly version number is changed
When an updated solution containing the revised assembly is imported, the assembly is considered a different assembly than the previous version of that assembly in the existing solution. Plug-in registration steps in the existing solution will continue to refer to the previous version of the assembly. If you want existing plug-in registration steps for the previous assembly to point to the revised assembly, you'll need to use the Plug-in Registration tool to manually change the step configuration to refer to the revised assembly type. This should be done before exporting the updated assembly into a solution for later import.
Unregister or disable plug-in components
You can unregister or disable plug-in components.
You can also delete Plug-in Assemblies and Sdk Message Processing Steps in the solution explorer to achieve the same result. In the figure below, a custom solution named Common Data Service Default Solution is shown.
You cannot delete any Plug-in Assemblies while existing Sdk Message Processing Steps depend on them. Entity images are not available to be deleted separately, but they will be deleted when any steps that use them are deleted.
The PRT provides commands to disable and enable steps.
You can also disable steps in the solution explorer using the Activate and Deactivate commands.