Programming Microsoft Dynamics CRM 4.0: Plug-ins

  • 12/15/2008


As stated earlier, every plug-in must implement the IPlugin interface, which includes the Execute method in its definition. The Execute method takes a single argument of type IPluginExecutionContext, which provides the plug-in with the state of the current execution pipeline and a means to communicate with the Microsoft Dynamics CRM Web service API. IPluginExecutionContext has twenty-two properties and two methods, all of which are described in the following list.

  • BusinessUnitId property. BusinessUnitId is a Guid that represents the business unit that the primary entity belongs to.

  • CallerOrigin property. CallerOrigin is an instance of one of the following classes:

    ApplicationOrigin, AsyncServiceOrigin, OfflineOrigin, or WebServiceApiOrigin. You can use this property to determine who initiated the pipeline. The following code determines whether the pipeline was initiated from the CRM Web service.

    public bool IsOriginatingFromWebServiceApi(IPluginExecutionContext context)
        return context.CallerOrigin is WebServiceApiOrigin;
  • CorrelationId, CorrelationUpdatedTime, and Depth properties. These three properties are combined to detect infinite loops in plug-ins. If you only use the IPluginExecutionContext interface’s CreateCrmService method to create CrmService instances, you don’t need to worry about these three properties, as they will be set on the returned CrmService for you. However, if you need to create your own instance of a CrmService class, you can use these properties to initialize its CorrelationTokenValue property, which ensures safety from infinite loops. The code shown here demonstrates how to use the correlation properties when creating your own CrmService instances.

    public CrmService GetSafeCrmService(IPluginExecutionContext context)
        CrmService crmService = new CrmService();
        crmService.CorrelationTokenValue = new CorrelationToken(
        // finish initializing crmService here...
        return crmService;
  • InitiatingUserId property. This property is always the Guid of the user that caused the event to execute, regardless of whether the plug-in was registered to impersonate another user. See the UserId property later in this section for more information.

  • InputParameters property. This property is an instance of Microsoft.Crm.Sdk. PropertyBag. Each value contained in PropertyBag corresponds with a property on the Request that caused this event to execute. For example, CreateRequest has a property named Target, so you would find a value in InputParameters with a key of "Target”.

    if (context.InputParameters.Contains(ParameterName.Target))
        DynamicEntity target = (DynamicEntity)
        // ...
  • InvocationSource property. The InvocationSource property is an integer value that you can use to determine whether the current plug-in is running in a child pipeline. Table 5-1 lists the valid values as defined by the MessageInvocationSource class.

    Table 5-1. MessageInvocationSource Values






    Specifies a child pipeline



    Specifies a parent pipeline

  • IsExecutingInOfflineMode property. You can register plug-ins to run offline with Microsoft CRM for Outlook with Offline Access. If a plug-in is running in such a state, this Boolean property is set to true. See Chapter 10 for more information on offline plug-ins.

  • MesssageName property. MessageName is a string property that allows the current plug-in to know the name of the message that is being executed (Create, Update, Assign, and so on).

  • Mode property. Mode is an integer property that you can use to determine whether the plug-in is executing synchronously or asynchronously. The valid values are from the MesssageProcessingMode class, as listed in Table 5-2.

    Table 5-2. MessageProcessingMode Values






    Specifies asynchronous processing



    Specifies synchronous processing

  • OrganizationId and OrganizationName properties. These properties contain information about the organization that the current entity belongs to and that the current pipeline is executing within.

  • OutputParameters property. Similar to the InputParameters property, this property is an instance of a PropertyBag. The values in the OutputParameters property correspond with the properties on the Response for the message being executed. For example, a CreateResponse has an Id property, so a post-event plug-in could expect the corresponding value in the OutputParameters property using a key value of “Id”.

    // Getting the entity id in a Post-Event for a Create message
    Guid contactId = (Guid)context.OutputParameters[ParameterName.Id];
  • ParentContext property. ParentContext is another instance of IPluginExecutionContext. If the current plug-in is executing in a child pipeline, ParentContext will contain the context of the parent pipeline; otherwise, ParentContext will be null.

  • PreEntityImages and. PostEntityImages properties PreEntityImages and PostEntityImages are both PropertyBag properties. When registering a plug-in, you can specify for certain messages that you want a snapshot of the entity before or after the core operation has completed. You also specify the alias you would like to give that snapshot. Those snapshots, or images, show up in these two collections with the alias as the key. PreEntityImages contains the images from before the core operation, and PostEntityImages contains the images from after the core operation.

  • PrimaryEntityName property. PrimaryEntityName is a string property that contains the name of the primary entity for which the pipeline is executing.

  • SecondaryEntityName property. SecondaryEntityName is a string property that contains the name of the secondary entity for which the pipeline is executing, if one exists. A majority of the messages deal with a single entity, so this property will almost always be set to “none”. However some messages, like SetRelated, refer to two entities. In this case, you can use SecondEntityName to find out the type of the second entity.

  • SharedVariables property. SharedVariables is a PropertyBag property that is meant to be used by plug-in developers to pass information between plug-ins. Using SharedVariables, a pre-event plug-in can pass along information to a post-event plug-in. Another potential use is to look up data in a parent pipeline step and then later access it in a child pipeline through the child’s ParentContext property’s SharedVariables property.

  • Stage property. Stage is an integer property that a plug-in can use to determine whether it is running as a pre-event or a post-event plug-in. The valid values are from the MessageProcessingStage class, as listed in Table 5-3.

    Table 5-3. MessageProcessingStage Values






    Specifies to process after the main operation, outside the transaction



    Specifies to process before the main operation, outside the transaction

  • UserId property. UserId is a Guid property that represents the user that the plug-in is running as for any CrmService calls. This value is typically the user that initiated the event, but if a plug-in is registered to impersonate another user, this value contains the impersonated user’s ID. See the InitiatingUserId property for more information.

  • CreateCrmService method. This is an overloaded method that you can use to create an instance of an ICrmService interface that has the same methods as the CrmService class, which is explained in detail in Chapter 3. The arguments control impersonation within the plug-in and are explored in more depth in the “Impersonation” section later in this chapter.

  • CreateMetadataService method. You use the CreateMetadataService method to get an instance of the IMetadataService interface that has the same methods as the MetadataService class, which is explained in detail in Chapter 3. The method accepts a single Boolean named useCurrentUserId and is used for impersonation with in the plug-in. See the next section, “Impersonation,” for more details.