DEVKIT1013 - phuocle/Dynamics-Crm-DevKit GitHub Wiki
This analyzer warns when a plugin is registered on Retrieve or RetrieveMultiple messages. These messages are called very frequently and plugins on them can significantly impact system performance.
📚 Limit the registration of plug-ins for Retrieve and RetrieveMultiple messages
Adding synchronous plug-in logic to the Retrieve and RetrieveMultiple message events can result in slowness. Consider using alternate design approaches if you require logic to run during these messages.
Plugins on Retrieve/RetrieveMultiple messages cause:
- Frequent Execution: These messages are called constantly during normal application use
- UI Slowdown: Every form load, lookup, and view triggers these messages
- Cascading Impact: Slow retrievals affect all parts of the system
- Scalability Issues: Performance degrades as user count increases
| Operation | Retrieve/RetrieveMultiple calls |
|---|---|
| Opening a form | Multiple calls per form |
| Loading a view | One RetrieveMultiple per view |
| Lookup search | RetrieveMultiple for each keystroke |
| Related records grid | RetrieveMultiple for each grid |
The analyzer flags [CrmPluginRegistration] attributes where:
- The message parameter is
"Retrieve" - The message parameter is
"RetrieveMultiple"
// ❌ Plugin on Retrieve - runs EVERY time any record is opened
[CrmPluginRegistration("Retrieve", "account", StageEnum.PostOperation,
ExecutionModeEnum.Synchronous, "", "Retrieve Account")]
public class RetrieveAccountPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// This runs on EVERY account form load!
}
}
// ❌ Plugin on RetrieveMultiple - runs EVERY time a view or lookup is loaded
[CrmPluginRegistration("RetrieveMultiple", "contact", StageEnum.PostOperation,
ExecutionModeEnum.Synchronous, "", "RetrieveMultiple Contact")]
public class RetrieveMultipleContactPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// This runs on EVERY contact view load!
}
}// ✅ Use Create/Update plugins to set calculated fields
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation,
ExecutionModeEnum.Synchronous, "revenue,numberofemployees", "Calculate Account Rating")]
public class CalculateAccountRatingPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Pre-calculate values during Update instead of during Retrieve
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var target = (Entity)context.InputParameters["Target"];
// Calculate and store the value
target["new_calculatedrating"] = CalculateRating(target);
}
}| Need | Alternative |
|---|---|
| Calculated fields | Use Create/Update to pre-calculate and store |
| Security filtering | Use row-level security or column-level security |
| Data transformation | Use Views with saved queries |
| External data | Use Virtual Entities |
| UI logic | Use JavaScript on form load |
- Pre-calculate Values: Store calculated values during Create/Update instead of computing during Retrieve
- Use Security Features: Row-level security, column security profiles, or field-level security
- Client-side Logic: Move logic to JavaScript for UI-specific needs
- Virtual Entities: Use for external data integration
- [CrmPluginRegistration("Retrieve", "account", ...)]
- public class RetrieveAccountPlugin : IPlugin
+ [CrmPluginRegistration("Update", "account", StageEnum.PreOperation,
+ ExecutionModeEnum.Synchronous, "revenue", "Pre-Calculate Values")]
+ public class PreCalculateAccountPlugin : IPluginIf you have a legitimate need for Retrieve/RetrieveMultiple plugins:
#pragma warning disable DEVKIT1013
[CrmPluginRegistration("Retrieve", "account", StageEnum.PostOperation,
ExecutionModeEnum.Synchronous, "", "Retrieve Account")]
#pragma warning restore DEVKIT1013Or in .editorconfig:
[*.cs]
dotnet_diagnostic.DEVKIT1013.severity = none| Property | Value |
|---|---|
| Rule ID | DEVKIT1013 |
| Category | DynamicsCrm.DevKit |
| Severity | Warning |
| Enabled by default | Yes |