In Dynamics 365, plugins have the concept of “depth”. This is how many times the plugin is firing based on certain events. The depth is part of the plugin context.
Let’s go through an example of how plugin depth works.
Create a new class library in Visual Studio:

Add some code to check the depth:
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;
namespace
Carl.PluginDepth
{
public
class
PluginDepthExample : IPlugin
{
public
void
Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace($"The plugin depth is: {context.Depth.ToString()}");
if
(context.Depth == 1)
{
// Do something
tracingService.Trace($"The plugin depth is: {context.Depth.ToString()}");
}
else
if
(context.Depth > 1)
{
// Do something else
tracingService.Trace($"The plugin depth is: {context.Depth.ToString()}");
}
}
}
}
Let’s runs this every time Accounts are retrieved.

On invoking our plugin by selecting a list of accounts:

We can see the plugin depth is 1:

Now let’s add some code to do another retrieve multiple in our plugin:
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;
namespace
Carl.PluginDepth
{
public
class
PluginDepthExample : IPlugin
{
public
void
Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace($"The plugin depth is: {context.Depth.ToString()}");
if
(context.Depth == 1)
{
// Do something
QueryExpression query = new
QueryExpression("account");
query.ColumnSet.AddColumns("name");
EntityCollection result = service.RetrieveMultiple(query);
tracingService.Trace($"The plugin depth is: {context.Depth.ToString()}");
}
else
if
(context.Depth > 1)
{
// Do something else
tracingService.Trace($"The plugin depth is: {context.Depth.ToString()}");
}
}
}
}
Now when we run this and refresh our data, we see there are 2 records created in our plugin profiles:

The first hits the if condition where Depth = 1 is hit. We then run our RetrieveMultiple:

The second hits the condition where the Depth = 2:
