- The connection from the opportunity to the user is created (your plugin triggers here as expected). Temporarily the “relatedconnectionid” attribute is set to the id of the connection getting created.
- A reciprocal (corresponding) connection is created from the user to the opportunity which uses the corresponding connection role if available (your plugin triggers again because of the create, but the primary entity here is a different connection record)
- Once the second connection is created then the system updates the first connection record to set the RelatedConnectionId to the connection created in step 2 (your plugin triggers again because of the update)
Now depending on your business logic you might want to avoid the plugin from triggering in step2 (or maybe not). If you do, you can use this trick inside your plugin to make sure that the plugin executes only for step1:
Entity creatingConnection = (Entity)context.InputParameters["Target"];
EntityReference relatedConnection = creatingConnection["relatedconnectionid"] as EntityReference;
if (relatedConnection != null && creatingConnection.Id != relatedConnection.Id)
{
// Creating reciprocal connection
// Return here if the plugin should not execute in step2.
}
EntityReference relatedConnection = creatingConnection["relatedconnectionid"] as EntityReference;
if (relatedConnection != null && creatingConnection.Id != relatedConnection.Id)
{
// Creating reciprocal connection
// Return here if the plugin should not execute in step2.
}
The other tricky aspect of plugins with connections is that sometimes your plugin gets called in the context of the SYSTEM user (even if you specify Calling User or another user in the Plugin Registration Tool). This happens at least every time you have a plugin registered on “Delete” of connection. The only workaround that you have, is that from your plugin, when you create the CRM service you impersonate back the initiating user:
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId);
IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId);
I hope you find this helpful!
Nice post!
ReplyDeleteCannot you test IsMaster attribute to distinguish between master and reciprocal?
ReplyDeleteThank you, it was helpful:)
ReplyDelete