Quantcast
Viewing latest article 1
Browse Latest Browse All 22

CRM Code Review Checklist

I’ve had the opportunity to experience some of the pros and cons of various coding styles and techniques over the years. Over time I myself have performed code reviews not only to address performance, but also to resolve execution failures that were not openly obvious. Below are some of the things I try to keep in mind whenever I sit down to look at code on a project.

  • Refactor deprecated API calls
  • Review list of new API’s and usage with development team when upgrading
  • Move late bound string literals of entity and attribute names into constants
  • Ensure plugin code is written for stateless execution
    • Remove use of class level variables
    • Do not attempt to cache variables in memory; constants are okay
  • Ensure service insert or update calls do not reuse existing entity objects and instead use new entity objects with only the required fields for the operation.
    • End result is columns that do not need to be changed or updated are impacted
    • Possible business logic triggered
    • Create a new entity and only assign the attributes you intend to update
    • Creates inaccurate audit history records
  • Use attribute filtering for triggering plugins and workflows to fire as much as possible
  • Refactor code that fires on child records that attempt to update a common ancestor record
  • Refactor code that retrieve information for the target record in a plugin to use pre and post images
    • Developers should instead leverage provided context mechanisms such as Input/OutputParameters and Pre/Post Event Images to access primary entity data.
  • Be mindful of and coordinate cascading business logic execution paths
    • e.g. Plugins that may cause other plugins and workflow  to fire
  • Review base class(es) used by plugins/workflows to ensure some component of the event pipeline isn’t being reference by a non-threadsafe member
  • Only retrieve the minimum necessary attributes for a business operation to perform its task
    •  Check for queries for usage of AllColumns()
  • In general lean towards synchronous execution over asynchronous to avoid system overhead
  • Optimize expensive code when possible
    • Code that queries large amounts of data
    • Code that queries a data set that continues to grow over time (sneaky performance impact)
    • Loops that query data on each iteration
  • Optimize expensive loops
    • Avoid repetitive field or property access
    • Replace recursion with looping
    • Use For instead of ForEach in performance-critical code paths
  • Exercise extreme caution with code that programmatically
    • Updates system users’ records, team memberships, security roles, business units
    • Creates new business units, teams, security roles
  • Use the string builder object when concatenating strings in loops
  • Refactor code that inappropriately doesn’t use CRM query paging to retrieve more than the default 5,000 records on a retrieve
  • Refactor code that updates the primary target entity in a post execution event
    • Potentially causes an infinite loop
  • Refactor use of non-cross-browser compatible code such as ActiveX objects in JavaScript
  • Avoid use of modal dialogs
    • Chrome and FireFox have deprecated support for modal dialogs.  CRM is being updated to eliminate all usage of modal dialogs
    • Replace all calls to alert(), confirm(), window.open (“”, “”, “modal=yes”), and window.showModalDialog() with an alternate user experience
    • Use Xrm.Utility.alertDialog() and .confirmDialog() as viable alternatives to window.alert()/confirm()
    • Do not use window.openStdDlg() which is an internal CRM function and considered unsupported.
  • Change all HTTP requests to send asynchronously
    • Sending sync requests will block the UI thread and negatively impact user experience due to a non-responsive window.
    • Implement an async request with callback handler function pattern. 
    • Form multiple, dependent requests you can chain subsequent requests in previous request callback.  If this becomes too complex, consider implementing the promise or final state machine pattern.
  • Refactor use of object properties in loop controllers to use a variable instead
  • Don’t create each plugin in for your solution in a separate solution (rather annoying)
  • When creating a new entity allow the system to generate the GUID’s instead of creating them yourself in code.
    • This will allow SQL to create sequential GUID’s which can be indexed easier.
  • When referencing web resources use relative paths to allow for caching
  • Explicitly call the close or dispose methods of disposable objects created during execution before they fall out of scope to minimize the life of the object in memory
    • This applies to things such as database connections, message queue handles, file handles, etc.
    • Either use try/finally blocks or using statements
  • Write code that avoids the use of exceptions to control program logic
    • Throwing exception as a general coding practice can cause performance issues
  • Ensure plugins only use InvalidPluginExceptionExecution to report exceptions to the platform
  • The CRM platform introduced cross-browser compatibility in CRM 2011 UR12 so don’t use browser specific API’s
  • Use feature detection instead of browser detection in client side code
  • Look for opportunities to use business rules for real-time workflows that perform a lot of updates.


Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.

Viewing latest article 1
Browse Latest Browse All 22

Trending Articles