Monday, August 28, 2023

Understanding Plugin Depth and Infinite Loop in Dynamics 365 CE

Title: Understanding Plugin Depth and Infinite Loop in Dynamics 365 CE 

  

Within Dynamics 365 Customer Engagement (CE) Plugin development Plugin Depth -Used by the platform for infinite loop prevention. In this blog, we'll demonstrate the plugin depth and its significance. 

  

 

To Learn more about Plugin Development: Follow:   

 

 

Understanding the Plugin Depth Property (IExecutionContext.Depth) 

 

Plugin Depth refers to the level at which your custom plugin execution is initiated in response to system events such as Create/ Update etc.  


Depth is used solely to manage potential infinite loops that could occur in plug-in or custom workflow activities. 


Every time a running plug-in or Workflow issues a message request to the Web services that triggers another plug-in or Workflow to execute, the Depth property of the execution context is increased. If the depth property increments to its maximum value within the configured time limit, the platform considers this behavior an infinite loop and further plug-in or Workflow execution is aborted. 


The maximum depth (8) and time limit (one hour). 


Type Int32 – Gets the current depth of execution in the call stack.

Starts with numeric 1

 

Let’s take an example:  

 

You have a Plugin Step on Change of Account Name, and you are updating the same Account Name from plugin code, this will create infinite loop in plugin execution, right? So, to stop this infinite loop we will use the Execution Context Depth concept.  


Another example would be, let's say you have plugin (on Account) which creates another table record (Contact) in one transaction, and you have plugin registered on Contact table, so Plugin Depth on Contact will be 2 (incremented by 1). And this goes on to max 8. 


If you do not use Depth in Plugin, you are potentially creating infinite loop and plugin will throw following exception:  

System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: This workflow job was canceled because the workflow that started it included an infinite loop. Correct the workflow logic and try again. For information about workflow logic, see Help. (Fault Detail is equal to Exception details.  





Plugin Code:  

 

using System; 

using System.Collections.Generic; 

using System.Linq; 

using System.Text; 

using System.Threading.Tasks; 

 

using System.ServiceModel; 

using Microsoft.Xrm.Sdk; 

 
 

namespace MyFirstDemoPlugin 

{ 

    public class PostAccountNameUpdate : IPlugin 

    { 

        public void Execute(IServiceProvider serviceProvider) 

        { 

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

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

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

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

  

            try 

            { 

                tracingService.Trace("PostAccountNameUpdate Started");  

 

                //Check Context Depth - and update Account Name only when Depth is 1 

                if (context.Depth == 1) 

                { 

                    //Do Something 

                    if (context.InputParameters["Target"] != null && context.InputParameters["Target"] is Entity entityAccount) 

                    { 

                        if (entityAccount.LogicalName == "account") 

                        { 

                            //update account name from Plugin 

                            Entity updateAccountObj = new Entity("account"); 

                            updateAccountObj.Attributes.Add("accountid", entityAccount.Id); 

                            updateAccountObj.Attributes.Add("name", "Account Name updated from Plugin"); 

 
 

                            service.Update(updateAccountObj); 

                            tracingService.Trace("Plugin Depth 1. Account Updated."); 

                        } 

                    } 

                } 

                else 

                { 

                    tracingService.Trace("Plugin Depth is greather than 1. Stopped"); 

                } 

 

                tracingService.Trace("PostAccountNameUpdate Finished"); 

            } 

            catch (Exception ex) 

            { 

                tracingService.Trace(ex.ToString()); 

            } 

        } 

    } 

} 

 

 

Plugin Step: 

 

 

When Plugin depth is 1 account updated from code, and when Plugin Depth more than 1 it skipped the update.  

 

  

Conclusion 

Plugin depth in Dynamics 365 CE is like a game changer in solving loop in Custom code. If you have multiple plugins running and triggering the same step from multiple locations, it's always recommended to use depth to stop loop.  

 

 

Stay tuned for more in-depth explorations into the Dynamics 365 CE Platform and Plugin Development. 

#Dynamics365 #Development #Plugin 

 


Next Steps: Learn more about other powerful features of Plugin! 


No comments:

Post a Comment