Plugin Development

A plugin is a .Net class that implements IPlugin interface.

public class MyFirstPlugin: IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        //Plugin Logic Code
    }
}

When a plugin is run in response to an execution pipeline event for which it is registered, the plugin's Execute method is called.

IPlugin Execute Method

IPlugin.Execute(IServiceProvider)

When a particular event occurs in Microsoft Dynamics CRM, such as “create of a contact” or “update of an account”, the Execute method is invoked for any plugins registered on the event.

This method includes a single serviceProvider parameter which provides useful service information about the execution of the plugin.

That method passes a System.IServiceProvider object as a parameter, which contains a number of useful objects.

The types of service objects available include the following:

  • IPluginExecutionContext

  • IOrganizationServiceFactory

  • ITracingService

    IPluginExecutionContext contains information that describes the runtime environment that the plugin executes, information related to the execution pipeline, and entity business information.

    The IPluginExecutionContext service object is the most useful of the three and provides contextual information to the plugin at run-time. It includes details about the user who triggered the plugin event as well as transactional information handled at the platform layer.

  • The following code can be used to obtain the execution context from the service provider:

      IPluginExecutionContext context =(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    
    • Most of these properties are read only.

      • UserId (It contains the user information under which the plugin is executed)

      • Message (It gives the information about the event for which the plugin is been raised)

      • Stage (It helps to identify under which stage the code should execute)

      • Depth (It tells the current depth the code is being executed)

        • Depth property is used to find the position of the plugin in the current call stack. To be simple, with this property, we can find whether the plugin is triggered by another process(plugin/workflow) or directly by platform/user.

        • Default depth value is 1.

        • If plugin depth is greater than 1, then it is triggered by another process. Depth of the plugin is incremented by 1, if called by another process.

        • There is a myth around depth, that it can be used to break infinite loops. Yes, they can, but these checks may become dangerous and may skip your plugin logic at times. For example, if a plugin from account triggers a plugin in contact, the depth in contact plugin is 2 and that is not an infinite loop.

      • InputParameters (It holds information related to the organization Web Service Request object)

        • The data that is in the request message currently being processed by the Execution Pipeline.

          • It will have two keys Target and OptionalParameters

            • Target is, really, the in-memory representation of the data that's being updated/created/deleted/etc. It is literally the target of the action.

            • Q1: Will the context be there for every Plugin execution?

              • Yes, it will.
            • Q2: Will the Target be there for every Plugin execution?

              • No, not necessarily. It depends on the Plugin step configuration. Remember we can register a Plugin for different messages? Not all of them will have a target. Although, messages like "Create"/"Update"/"Delete" will have a Target.
            • Q3: How do you know what you will find in the "Target"?

              • For the "Create" and "Update" plugins, you will always have a "Target", and it will be of "Entity" type.

              • For the "Delete" plugins, you will also have a "Target", but it will be of "EntityReference" type.

      • OutputParameters ()

        • Data that is in the response message. It is populated by the platform and only contains valid data during the After Operation Stage.
      • PreEntityImage

      • PostEntityImage etc.

  • IOrganizationSurviceFactory to access the Organisation service. In order to perform any CRUD operation.

    • The IOrganizationServiceFactory service object allows us to create an instance of the organization service which can be used to define and execute various platform requests. The following code can be used to achieve this:

    •       IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService sdk = factory.CreateOrganizationService(context.UserId);
      

      In the example above, we pass in the GUID of the user who triggered the plugin event, which is obtained from the IPluginExecutionContext. Alternatively, we can pass in the GUID of another CRM user, or pass in a null value to execute the plugin logic under the system context.

  • ITracingService allows us to trace the plugin execution flow and any variables for debugging purposes.

  • IServiceEndpointNotificationService for synchronous plugins, it is used to post Execution Context to Azure Service Bus.

Plugin Pre/Post Event Images

It is a snapshot of entity state at that point in time. It removes the need to call retrieve request to get entity during execution.

The attributes should be specified in the registration.

It is available via IPluginExecutionContext properties at runtime.

  1. PreEntityImage

  2. PostEntityImage

Step by step process of writing a Plugin

  1. Download CRM SDK. This will provide you with all the information such as SDK assemblies etc.

  2. Create a project of type class library.

  3. Add reference of Microsoft.XRM.Sdk.dll and Microsoft.Crm.Sdk.Proxy.dll assembly references to the project in SDK/Bin folder.

  4. Add a class and Extend it from IPlugin.

  5. Write the plugin code/logic in the Execute Method.

  6. At the project, sign the assembly. This is required in order to be able deploy the plugin.

  7. Compile the assembly and deploy using Plugin Registration Tool.