DEVKIT1003 - phuocle/Dynamics-Crm-DevKit GitHub Wiki
This analyzer validates that plugin image configurations (Pre-Images and Post-Images) are compatible with the message and stage. The Dynamics 365 platform has specific rules about when images are available, and incorrect configurations will cause runtime errors.
📚 Understand the execution context
Pre-entity images contain data as it existed before the operation. Post-entity images contain data as it exists after the operation. Not all operations support both types of images.
Configuring unavailable images causes:
- Runtime Errors: Plugins will fail at execution time
- Deployment Failures: Solution import may fail with invalid step configurations
- Debugging Difficulty: Errors may not be obvious until runtime
- Data Integrity Issues: Failed plugins may leave data in inconsistent states
| Message | Stage | Pre-Image | Post-Image |
|---|---|---|---|
| Create | Pre-Validation | ❌ | ❌ |
| Create | Pre-Operation | ❌ | ❌ |
| Create | Post-Operation | ❌ | ✅ |
| Update | Pre-Validation | ✅ | ❌ |
| Update | Pre-Operation | ✅ | ❌ |
| Update | Post-Operation | ✅ | ✅ |
| Delete | Pre-Validation | ✅ | ❌ |
| Delete | Pre-Operation | ✅ | ❌ |
| Delete | Post-Operation | ✅ | ❌ |
The analyzer flags [CrmPluginRegistration] attributes where:
- Image configurations are incompatible with the message/stage combination
- Pre-Image on Create (record doesn't exist yet)
- Post-Image on Pre-Operation stages (changes not committed yet)
- Post-Image on Delete (record is deleted)
// Pre-Create cannot have Pre-Image - record doesn't exist yet!
[CrmPluginRegistration("Create", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
Image1Type = ImageTypeEnum.PreImage,
Image1Name = "PreImage",
Image1Attributes = "name,accountnumber")]
public class PreCreateWithPreImage : IPlugin { }
// Pre-Update cannot have Post-Image - changes not committed yet!
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
Image1Type = ImageTypeEnum.PostImage,
Image1Name = "PostImage",
Image1Attributes = "name")]
public class PreUpdateWithPostImage : IPlugin { }
// Delete cannot have Post-Image - record is deleted!
[CrmPluginRegistration("Delete", "account", StageEnum.PostOperation, ExecutionModeEnum.Synchronous,
Image1Type = ImageTypeEnum.PostImage,
Image1Name = "PostImage",
Image1Attributes = "name")]
public class PostDeleteWithPostImage : IPlugin { }// Post-Create can have Post-Image
[CrmPluginRegistration("Create", "account", StageEnum.PostOperation, ExecutionModeEnum.Synchronous,
Image1Type = ImageTypeEnum.PostImage,
Image1Name = "PostImage",
Image1Attributes = "name,accountnumber")]
public class PostCreateWithPostImage : IPlugin { }
// Pre-Update can have Pre-Image
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
Image1Type = ImageTypeEnum.PreImage,
Image1Name = "PreImage",
Image1Attributes = "name,accountnumber")]
public class PreUpdateWithPreImage : IPlugin { }
// Post-Update can have BOTH images
[CrmPluginRegistration("Update", "account", StageEnum.PostOperation, ExecutionModeEnum.Synchronous,
Image1Type = ImageTypeEnum.PreImage,
Image1Name = "PreImage",
Image1Attributes = "name",
Image2Type = ImageTypeEnum.PostImage,
Image2Name = "PostImage",
Image2Attributes = "name")]
public class PostUpdateWithBothImages : IPlugin { }- Check the Matrix: Refer to the Image Availability Matrix above
- Adjust Stage or Image Type: Either change the stage or remove the incompatible image
-
Use Target Entity: For Create messages, use
Targetfrom InputParameters instead of images
- [CrmPluginRegistration("Create", "account", StageEnum.PreOperation,
- Image1Type = ImageTypeEnum.PreImage, Image1Attributes = "name")]
+ [CrmPluginRegistration("Create", "account", StageEnum.PostOperation,
+ Image1Type = ImageTypeEnum.PostImage, Image1Attributes = "name")]If you have a legitimate need to suppress this warning:
#pragma warning disable DEVKIT1003
[CrmPluginRegistration("Create", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
Image1Type = ImageTypeEnum.PreImage, Image1Attributes = "name")]
#pragma warning restore DEVKIT1003Or in .editorconfig:
[*.cs]
dotnet_diagnostic.DEVKIT1003.severity = none| Property | Value |
|---|---|
| Rule ID | DEVKIT1003 |
| Category | DynamicsCrm.DevKit |
| Severity | Error |
| Enabled by default | Yes |