When developing Microsoft Dynamics 365 or Dataverse plugins, writing clean and maintainable code is essential. One of the best practices is replacing hardcoded strings with constants and using Pre-Images to compare old and new values during update operations.
In this article, we'll analyze a simple Update Plugin that automatically updates a target field whenever a source field changes.
Why Use Constants?
Many Dynamics 365 plugins contain repeated strings such as:
Entity logical names
Attribute names
Image names
Fixed values
Hardcoding these values throughout the code makes maintenance difficult and increases the risk of typing errors.
Instead, define constants:
private const string ENTITY_NAME = "new_entity";
private const string FIELD_SOURCE = "new_fieldsource";
private const string FIELD_TARGET = "new_fieldtarget";
private const string PREIMAGE_NAME = "PreImage";
private const string VALUE_OK = "OK";
private const string VALUE_CHANGED = "CHANGED";
This approach improves readability and makes future modifications easier.
Plugin Overview
The plugin executes on the Update message.
Its purpose is simple:
Retrieve the old value from the Pre-Image.
Retrieve the new value from the Target entity.
Compare both values.
Update another field based on the result.
Step 1: Verify the Message
The first check ensures the plugin only runs during update operations.
if (context.MessageName != "Update")
return;
This prevents unnecessary execution for Create, Delete, or other messages.
Step 2: Retrieve the Target Entity
The plugin verifies that the Target parameter exists.
if (!context.InputParameters.Contains("Target"))
return;
var target = (Entity)context.InputParameters["Target"];
The Target contains only the attributes that have been modified.
Step 3: Validate the Entity
To avoid executing on unintended tables, the plugin checks the logical name.
if (target.LogicalName != ENTITY_NAME)
return;
This guarantees the plugin runs only for the expected entity.
Using Pre-Images
A Pre-Image contains the record values before the update operation.
The plugin retrieves the image using:
if (!context.PreEntityImages.Contains(PREIMAGE_NAME))
throw new InvalidPluginExecutionException("PreImage missing");
var preImage = context.PreEntityImages[PREIMAGE_NAME];
If the image is not registered, the plugin throws an exception.
Why Pre-Images Matter
Without a Pre-Image, the plugin cannot determine whether a field value has changed.
Pre-Images are especially useful when:
Detecting changes
Auditing data
Triggering business logic only when specific fields are modified
Reducing unnecessary updates
Comparing Old and New Values
The plugin retrieves the original value from the Pre-Image:
string oldValue = preImage.Contains(FIELD_SOURCE)
? preImage.GetAttributeValue<string>(FIELD_SOURCE)
: null;
Then it determines the new value:
string newValue = target.Contains(FIELD_SOURCE)
? target.GetAttributeValue<string>(FIELD_SOURCE)
: oldValue;
This logic handles cases where the source field is not included in the update request.
Applying Business Logic
The comparison is straightforward:
if (oldValue != newValue)
{
target[FIELD_TARGET] = VALUE_CHANGED;
}
else
{
target[FIELD_TARGET] = VALUE_OK;
}
If the source field changes, the target field receives the value:
CHANGED
Otherwise:
OK
Because the plugin modifies the Target entity during the update pipeline, no additional service update call is required.
Registration Requirements
When registering the plugin, configure:
Message
Update
Primary Entity
new_entity
Execution Stage
Recommended:
Pre-Operation
Pre-Image
Name:
PreImage
Attributes:
new_fieldsource
Benefits of This Approach
This implementation provides several advantages:
Cleaner code through constants
Easier maintenance
Better readability
Reliable change detection
Reduced risk of typos
No extra database update operations
Using constants and Pre-Images is a simple but powerful technique when developing Dynamics 365 plugins. By avoiding hardcoded values and comparing old and new data efficiently, you can build more robust, maintainable, and scalable business logic.