During a recent Dynamics CRM 2011 code review engagement, I noticed a pattern being implemented repeatedly throughout the customer's plug-in library. This library was in desperate need of a refactor in the form of a method that encapsulated the repeated pattern. In my assessment report, I provided them a suggested method refactor which could eliminated hundreds of lines of redundant plug-in code. Keep reading and I'll provide you this same method to put in your coding arsenal.
The pattern I identified sought to incorporate the values from pre-event entity image snapshots when evaluating the primary entity's attribute values. We most often see this scenario for pre-event Update message plug-in code. The need for such a pattern is dictated by the nature of the Update message where the entity submitted only contains the attributes to be updated. Makes perfect sense…until you are executing within the event pipeline and need to evaluate a condition based on another attribute of the entity that may or may not have been submitted with the update.
Enter pre (and post) event image registrations. Event images provide a snapshot of the primary entity prior to (or after) the requested operation. This capability allows you to have broader context about the entity state without having to incur unnecessary retrieval of the primary entity from within your plug-in operation. Nevertheless, having this additional context means that you have two potential sources for the value of an entity attribute. Handling this unique situation requires additional logic to determine the appropriate value. The logic goes something like this:
- Attempt to get the attribute value from the primary entity
- If the primary entity contains the attribute, use its value
- Otherwise, if the primary entity doesn't contain the attribute, attempt to get the attribute from the pre-event image entity
- If the pre-event image entity contains the attribute, use its value
- Otherwise, use some default value (or null)
First, let's take a look at how this logic is often implemented in code.
Next, we'll take the logic implemented above and encapsulate it in a method. I chose an extension method in this case to provide fluent companion to the standard Entity.GetAttributeValue<T>(string attributeLogicalName) method.
How does incorporating our new extension method impact the original code? As shown below, each instance of executing this logic has been reduced to a single line of code. Implement this logic even a few times in a single plug-in and the reductions add up quickly.
Remember, if logic is worth repeating, it’s worth implementing once as a method!
Please let us know if the timing is right to explore a Code Review service engagement for your CRM solution or if you’re interested in becoming a Microsoft Premier Services customer.