Skip to main content

Notifications

Microsoft Dynamics CRM (Archived)

Plugin Dependency

Posted on by 395

Hi,

I am running into an issue with plug-in dependency. Can some one provide a resolution for this problem.

I have created a generic plug-in that creates connection record for Lead or Opportunity. I have registered the plug-in on Lead and Opportunity create. There are 2 scenarios where a dynamic connection get created.

I have one more plug-in that is registered on Connection entity create as well.

1. Dynamically create the connection when a lead or opportunity record is created. I registered this plug-in on Lead and Opportunity create step. There is some business logic that will change the Connection Role and creates it. This works fine if the second plug in mentioned in point 2 is disabled.
2. I have another plug-in registered on Connection entity for create step. There is some business logic when the user manually saves a connection record from connection form.

These two are conflicting each other and when i save the Lead Record the second plug-in that is registered against connection create step also getting called and erroring out.

I am trying to disable the second plug-in that is registered on Connection create step whenever the Lead record is getting created. I dont want to disable the second plug-in and enable it after the record is created but i felt thats the only option to make it work but some times its working and some times its not working. May be because of the plug-in refresh during Enable/Disable not sure yet.

Is there any way i can create this dependency and dont call the 2nd plug-in that i registered on connection entity whenever the lead record is created?

*This post is locked for comments

  • Suggested answer
    RaviKashyap Profile Picture
    RaviKashyap 55,410 on at
    RE: Plugin Dependency

    Hi SVN,

    I am confused :(.

    In your questions you said you have generic plugin which triggers on create of Lead, Connection & Opportunity but the ode doesn't have opportunity part. You said you have another plugin which triggers on connection create, what does that look like?

    Also, as per you code, you are creating connection in plugin and also have a step registered for the same plugin on create of connection. I think this will go into the infinite loop thingy.

    You mentioned it is working fine when you are debugging, Did you try to use Depth in your plugin. see if it helps.

    =====

    if (context.Depth > 1)

    ======

    community.dynamics.com/.../crm-plugins-stopping-infinite-loops-and-understanding-pluginexecutioncontext-depth

    I always try to make things simple instead of getting into making the things "Generic" and then banging my head when its not working.

    Hope this helps.

  • Srini20 Profile Picture
    Srini20 395 on at
    RE: Plugin Dependency

    Thanks Alex. Yes i am setting the connection role. I figured that the problem is with the record1 attribute check.

  • ashlega Profile Picture
    ashlega 34,475 on at
    RE: Plugin Dependency

    Hi SVN,

     it's a big piece of code, so.. But do you have a connection role for those two record types?

     You said it's not failing when you are debugging - were you using "replay plugin execution" option (in which case it would not be creating any records)

  • Srini20 Profile Picture
    Srini20 395 on at
    RE: Plugin Dependency

    Thanks Ravi.  I am getting this error "The record type 1 is not defined for use with the connection role"  but if i disable the plug-in on Connection entity and refresh the page then it works fine. If i enable the connection entity plug-in then i am getting this error. I followed the execution order Lead Plugin 1 and Connection Plug in 2 that are registered for Create step. Both are registered on sync /Post. Individual plug-in works  fine. I tried by separating the code into two different plug-in but couldn't get much help. Same plug-in works fine for Opportunity create as well. I can create the opportunity and Connections separately but the Lead plug-in is not working.

  • Srini20 Profile Picture
    Srini20 395 on at
    RE: Plugin Dependency

    Thanks Alex. I tried that option as well. I was getting "The record type 1 is not defined for use with the connection role" error but when i was debugging both the plug-ins it doesn't show error once and doesn't create the record that it needs to create. Here is the generic code that i am using and registered on Lead Create and Connection Create plug-ins. Can you suggest any other alternatives or some thing wrong with this approach that i followed?

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    using Microsoft.Xrm.Sdk;

    using Microsoft.Xrm.Sdk.Query;

    using System.ServiceModel;

    using System.Runtime.Serialization;

    using System.Web;

    using System.Xml;

    using Microsoft.Crm.Sdk.Messages;

    namespace LeadConnection

    {

       public class LeadConnection : IPlugin

       {

           public void Execute(IServiceProvider serviceProvider)

           {

               ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

               IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IExecutionContext));

               IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

               IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

               Entity entity = (Entity)context.InputParameters["Target"];

               string connectionCheck = string.Empty;

               if (entity.Attributes.Contains("sm_createconnectioncheck"))

               {

                   connectionCheck = entity.Attributes["sm_createconnectioncheck"].ToString();

               }

               if (entity.LogicalName == "lead")

               {

                   CreateDefaultConnection(service, tracingService, context, entity);

               }

               else if (entity.LogicalName == "connection" && connectionCheck != "No")

               {

                   CreateConnection(service, tracingService, context, entity);

               }

           }

           public void CreateDefaultConnection(IOrganizationService service, ITracingService tracingService, IPluginExecutionContext context, Entity entity)

           {

               try

               {

                   string message = context.MessageName.ToLower();

                   string amrAccountUser = string.Empty;

                   if (entity.LogicalName == "lead")

                       amrAccountUser = entity.Attributes["sm_clientgroup"].ToString();

                   else if (entity.LogicalName == "opportunity")

                       amrAccountUser = entity.Attributes["sm_clientgroup_opp"].ToString();

                   Guid contactid = ((EntityReference)entity.Attributes["parentcontactid"]).Id;

                   if (contactid == null)

                       return;

                   if (amrAccountUser == "BGT" && (message == "create"))

                   {

                       Guid id = Guid.NewGuid();

                       if (entity.LogicalName == "lead")

                           id = (Guid)entity.Attributes["leadid"];

                       else if (entity.LogicalName == "opportunity")

                           id = (Guid)entity.Attributes["opportunityid"];

                       QueryExpression query = new QueryExpression("contact");

                       EntityCollection Result = null;

                       var columnNames = new[] { "fullname", "emailaddress1" };

                       FilterExpression filterExpression = new FilterExpression(LogicalOperator.And);

                       filterExpression.AddCondition("contactid", ConditionOperator.Equal, contactid);

                       query.ColumnSet.AddColumns(columnNames);

                       query.Criteria = filterExpression;

                       query.LinkEntities.Add(new LinkEntity("contact", "account", "parentcustomerid", "accountid", JoinOperator.LeftOuter));

                       query.LinkEntities[0].Columns.AddColumn("psm_accounttype");

                       query.LinkEntities[0].Columns.AddColumn("accountid");

                       query.LinkEntities[0].Columns.AddColumn("accountnumber");

                       Result = service.RetrieveMultiple(query);

                       string accountType = Result.Entities[0].FormattedValues["account1.psm_accounttype"].ToString();

                       string associatedAccount = "";

                       if (Result != null && Result.Entities.Any())

                           associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();

                       else

                           return;

                       Guid accountid = new Guid(associatedAccount);

                       string connectionRoleValue = "";

                       if (accountType == "Test Broker")

                       {

                           connectionRoleValue = "Test Broker 1111";

                       }

                       else if (accountType == "Test Broker2")

                       {

                           connectionRoleValue = "Test Broker 22222";

                       }

                       else

                       {

                           connectionRoleValue = "Default";

                       }

                       EntityCollection connectionResult = GetConnectionRole(service, connectionRoleValue);

                       if (connectionResult == null || !connectionResult.Entities.Any())

                           return;

                       Entity connection = new Entity();

                       connection.LogicalName = "connection";

                       if (entity.LogicalName == "lead")

                           connection.Attributes.Add("record1id", new EntityReference("lead", id));

                       else if (entity.LogicalName == "opportunity")

                           connection.Attributes.Add("record1id", new EntityReference("opportunity", id));

                       connection.Attributes.Add("record2id", new EntityReference("account", accountid));

                       connection.Attributes.Add("record2roleid", new EntityReference("connectionrole", new Guid(connectionResult.Entities[0].Attributes["connectionroleid"].ToString())));

                       connection.Attributes.Add("sm_createconnectioncheck", "No");

                       service.Create(connection);

                   }

               }

               catch (FaultException<OrganizationServiceFault> ex)

               {

                   tracingService.Trace("Error Occurred in Create Lead Connection Plugin: " + ex.Message);

                   throw new InvalidPluginExecutionException("An error occurred in the Lead Connection Plugin.", ex);

               }

               catch (Exception ex)

               {

                   tracingService.Trace("Error Occurred in Create Lead Connection :", ex);

                   throw;

               }

           }

           private EntityCollection GetConnectionRole(IOrganizationService service, string connectionRoleValue)

           {

               //Retrieve Connection Role Guids...

               QueryExpression queryConnectionRole = new QueryExpression("connectionrole")

               {

                   ColumnSet = new ColumnSet("connectionroleid", "name"),

                   Criteria = new FilterExpression

                   {

                       Conditions =

                               {

                                   new ConditionExpression

                                   {

                                       AttributeName = "name",

                                       Operator = ConditionOperator.Equal,

                                       Values = { connectionRoleValue }

                                   }

                               }

                   }

               };

               EntityCollection connectionResult = service.RetrieveMultiple(queryConnectionRole);

               return connectionResult;

           }

           public void CreateConnection(IOrganizationService service, ITracingService tracingService, IPluginExecutionContext context, Entity entity)

           {

               try

               {

                   string message = context.MessageName.ToLower();

                   string amrAccountUser = string.Empty;

                   if (message == "create")

                   {

                       Guid record2Id = ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record2id"])).Id;

                       Guid record1Id = ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record1id"])).Id;

                       QueryExpression query = new QueryExpression("contact");

                       EntityCollection Result = null;

                       var columnNames = new[] { "fullname", "emailaddress1" };

                       FilterExpression filterExpression = new FilterExpression(LogicalOperator.And);

                       filterExpression.AddCondition("contactid", ConditionOperator.Equal, record1Id);//record1Id Contact Id that is selected in lookup.

                       query.ColumnSet.AddColumns(columnNames);

                       query.Criteria = filterExpression;

                       query.LinkEntities.Add(new LinkEntity("contact", "account", "parentcustomerid", "accountid", JoinOperator.LeftOuter));

                       query.LinkEntities[0].Columns.AddColumn("accountid");

                       query.LinkEntities[0].Columns.AddColumn("accountnumber");

                       Result = service.RetrieveMultiple(query);

                       //string associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();//retrive the associated account to the selected contact.

                       string associatedAccount = "";

                       if (Result != null && Result.Entities.Any())

                       {

                           associatedAccount = ((AliasedValue)Result.Entities[0]["account1.accountid"]).Value.ToString();

                       }

                       else

                           return;

                       Guid accountid = new Guid(associatedAccount);

                       //Retrieve the selected connection role..

                       Entity connectionEntity = new Entity();

                       var conRoleColumns = new[] { "name" };

                       ColumnSet connColumns = new ColumnSet(conRoleColumns);

                       connectionEntity = service.Retrieve("connectionrole", ((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record1roleid"])).Id, connColumns);

                       string connectionRoleValue = connectionEntity.Attributes["name"].ToString(); //Connection role referenced entity. Role value doesn't exist in Connection so retrieve with additional call.

                       if (connectionRoleValue == "Testing Locatoin1")

                       {

                           connectionRoleValue = "Testing Main Location1";

                       }

                       else if (connectionRoleValue == "Test Locatio2")

                       {

                           connectionRoleValue = "Testing Main Location2";

                       }

                       EntityCollection connectionResult = GetConnectionRole(service, connectionRoleValue);

                       if (connectionResult == null || !connectionResult.Entities.Any())

                           return;

                       Entity connection = new Entity();

                       connection.LogicalName = "connection";

                       //Dynamics check to create the connection for Opportunity or Lead based on where the connection is selectd.

                       if (((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record2id"])).LogicalName == "opportunity")

                           connection.Attributes.Add("record1id", new EntityReference("opportunity", record2Id));

                       else if (((Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["record2id"])).LogicalName == "lead")

                           connection.Attributes.Add("record1id", new EntityReference("lead", record2Id));

                       connection.Attributes.Add("record2id", new EntityReference("account", accountid));

                       connection.Attributes.Add("record2roleid", new EntityReference("connectionrole", new Guid(connectionResult.Entities[0].Attributes["connectionroleid"].ToString())));

                       service.Create(connection);

                   }

               }

               catch (FaultException<OrganizationServiceFault> ex)

               {

                   tracingService.Trace("Error Occurred in Create Connection Plugin: " + ex.Message);

                   throw new InvalidPluginExecutionException("An error occurred in the Lead Connection Plugin.", ex);

               }

               catch (Exception ex)

               {

                   tracingService.Trace("Error Occurred in Create Connection Connection :", ex);

                   throw;

               }

           }

           public static void EnablePlugin(IOrganizationService orgService, bool enable)

           {

               var messapgeProcessQE = new QueryExpression("sdkmessageprocessingstep");

               messapgeProcessQE.ColumnSet.AddColumns("sdkmessageprocessingstepid", "name");

               EntityCollection obj = orgService.RetrieveMultiple(messapgeProcessQE);

               int pluginStateCode = enable ? 0 : 1;

               int pluginStatusCode = enable ? 1 : 2;

               //Connection Step

               Guid stepId = new Guid("cdcd5b74-ea0c-e811-80f1-3863bb34ecf0");

               orgService.Execute(new SetStateRequest

               {

                   EntityMoniker = new EntityReference("sdkmessageprocessingstep", stepId),

                   State = new OptionSetValue(pluginStateCode),

                   Status = new OptionSetValue(pluginStatusCode)

               });

           }

       }

    }

  • RaviKashyap Profile Picture
    RaviKashyap 55,410 on at
    RE: Plugin Dependency

    Hi SVN,

    What's the error you are getting? How these plugins are registered, async/ sync, pre/post etc. Did you set the execution order of these plugins?

  • Suggested answer
    ashlega Profile Picture
    ashlega 34,475 on at
    RE: Plugin Dependency

    Create a custom field on the connection entity, populate it from your first plugin, and, in the second plugin, see if that field is in the context Target. If it's there, do nothing in the second plugin. If it's not there, the connection record is being created manually.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Suggested Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,253 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,188 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans