DEVKIT1001 - phuocle/Dynamics-Crm-DevKit GitHub Wiki
This analyzer ensures that plugin registrations for Create, CreateMultiple, Update, UpdateMultiple, OnExternalCreated, or OnExternalUpdated messages include specific filtering attributes. Without filtering attributes, the plugin executes on every field change, which can significantly impact performance.
📚 Include filtering attributes with plug-in registration
Adding synchronous plug-in logic to Create or Update message events without including filtering attributes will cause the plug-in logic to be executed for any change to the entity. This can slow down the performance of the system.
When you register a plugin on Create or Update messages without filtering attributes:
- Performance Impact: The plugin fires for every create/update, even if fields the plugin doesn't care about are modified
- Unnecessary Execution: Users experience delays when modifying unrelated fields
- Resource Waste: Server resources are consumed processing changes that don't require plugin logic
- Potential Cascading Issues: Other plugins and workflows may be delayed
| Message | Supports Filtering |
|---|---|
Create |
✅ |
CreateMultiple |
✅ |
OnExternalCreated |
✅ |
Update |
✅ |
UpdateMultiple |
✅ |
OnExternalUpdated |
✅ |
The analyzer flags [CrmPluginRegistration] attributes where:
- The message is
Create,CreateMultiple,Update,UpdateMultiple,OnExternalCreated, orOnExternalUpdated - The
filteringAttributesparameter is empty string (""), asterisk ("*"), or not specified
// Create with empty filtering - fires on EVERY create
[CrmPluginRegistration("Create", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
filteringAttributes: "",
stepName: "Pre-Create Account")]
public class AccountCreate : IPlugin
{
public void Execute(IServiceProvider serviceProvider) { }
}
// Using asterisk - equivalent to no filter
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
filteringAttributes: "*",
stepName: "Pre-Update Account")]
public class AccountUpdate : IPlugin
{
public void Execute(IServiceProvider serviceProvider) { }
}// Create - only fires when name or accountnumber is provided
[CrmPluginRegistration("Create", "account", StageEnum.PostOperation, ExecutionModeEnum.Synchronous,
filteringAttributes: "name,accountnumber",
stepName: "Post-Create Account")]
public class AccountCreate : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// This code only runs when 'name' or 'accountnumber' is provided during creation
}
}
// Update - only fires when name or accountnumber changes
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
filteringAttributes: "name,accountnumber",
stepName: "Pre-Update Account")]
public class AccountUpdate : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// This code only runs when 'name' or 'accountnumber' is modified
}
}- Identify Required Fields: Determine which fields your plugin actually needs to respond to
-
Add Filtering Attributes: Specify only those field names in the
filteringAttributesparameter - Use Comma Separation: Multiple fields should be separated by commas without spaces
- filteringAttributes: ""
+ filteringAttributes: "name,accountnumber"If you have a legitimate need to suppress this warning:
#pragma warning disable DEVKIT1001
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
filteringAttributes: "",
stepName: "Pre-Update Account")]
#pragma warning restore DEVKIT1001Or in .editorconfig:
[*.cs]
dotnet_diagnostic.DEVKIT1001.severity = none| Property | Value |
|---|---|
| Rule ID | DEVKIT1001 |
| Category | DynamicsCrm.DevKit |
| Severity | Error |
| Enabled by default | Yes |