Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.
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(
context.CorrelationId,
context.CorrelationUpdatedTime,
context.Depth
);
// finish initializing crmService here...
return crmService;
}More Info
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”.
Tip
When accessing the values in InputParameters, you should use the ParameterNames static class, instead of typing keys, to avoid run-time errors caused by typos. |
if (context.InputParameters.Contains(ParameterName.Target))
{
DynamicEntity target = (DynamicEntity)
context.InputParameters[ParameterName.Target];
// ...
}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.
| Field | Value | Description |
|---|---|---|
| Child | 1 | Specifies a child pipeline |
| Parent | 0 | 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.
| Field | Value | Description |
|---|---|---|
| Asynchronous | 1 | Specifies asynchronous processing |
| Synchronous | 0 | 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.
Caution
The initial release of Microsoft Dynamics CRM 4.0 had a bug that caused the friendly organization name to be passed into the plug-in execution context instead of the actual name. When you create an organization, these two values are the same by default, but if they are different you can run into issues quickly. The main problem is that when you use the CreateCrmService method, an invalid organization is specified for the ICrmService proxy and any calls you make with it result in an unauthorized exception. At the time this book went to press, Microsoft was aware of the defect and was implementing a fix, but until the fix is released you can just keep the organization name and the friendly name identical. |
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”.
Tip
Using the static ParameterNames class instead of string keys is encouraged so that you’ll discover errors at compile time instead of at run time. |
// 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.
| Field | Value | Description |
|---|---|---|
| AfterMainOperationOutsideTransaction | 50 | Specifies to process after the main operation, outside the transaction |
| BeforeMainOperationOutsideTransaction | 10 | Specifies to process before the main operation, outside the transaction |
More Info
There are, in fact, three other values for Stage, but they are for internal use only by Microsoft Dynamics CRM and you will receive an error if you try to register your plug-in to run in one of these stages. Just in case you run into one of these values while trying to debug an issue, they are BeforeMainOperationInsideTransaction (20), MainOperation (30), and AfterMainOperationInsideTransaction (40). |
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.