Quantcast
Channel: Weaponized CRM
Viewing all articles
Browse latest Browse all 22

CRM Code Review Checklist

$
0
0

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.



Viewing all articles
Browse latest Browse all 22

Trending Articles