Are You Gonna Be My Girl....
Over the last couple of months I've been spending quite a bit of time with the SDK, building custom workflow activities and plug-ins for CRM 4.0. One of the problems working with the IPlugin interface is that you are forced to use the DynamicEntity class when accessing the InputParameters and OutputParameters properties of the plug-in context.
This wouldn't be so bad, except that it is a real pain trying to find out what properties and values are actually contained within a Dynamic Entity whilst debugging and so I kept having to write the same "test harness" code over and over again just to examine their contents. However, last week I found out you can actually extend Visual Studio to provide this support by implementing a custom debugger visualizer.
Custom debugger visualizers were introduced in Visual Studio 2005 and enable you to view the contents of an object or variable in a meaningful way whilst debugging your application. Out of the box, Visual Studio ships with four standard visualizers, including the "Text Visualizer", "HTML Visualizer", and "XML Visualizer", all of which work on string objects, and the "DataSet Visualizer", which works for DataSet, DataView, and DataTable objects. However, none of these understand the how to work with the complexities of DynamicEntity object.
Fortunately there is plenty of information available online (how to write a visualizer, Creating Debugger Visualizers with Visual Studio 2005), and even a good Channel9 video interview with the Visual Studio program manager responsible for this feature - Scott Nonnenberg - Visualizers in VS 2005. This is well worth watching if you want to really understand how you can improve your debugging experience.
After playing around with this for a few hours I came up with a really cool solution using a TreeView and DataGridView control to provide detailed drill-down into dynamic entities. As you can see below, whenever the Visual Studio comes across an object of type Microsoft.Crm.Sdk.DynamicEntity, the visualizer is represented in the debugger by a magnifying glass icon. When you see the magnifying glass in a DataTip, in a debugger variables window or in the QuickWatch dialog box, you can click on the magnifying glass to select the DynamicEntity Visualizer.
Once launched, the DynamicEntity Visualizer iterates through all the dynamic entity properties to build a tree view on the left side of the form, showing the property name and the property type. Clicking on each property, displays the property attributes in a table on the right side of the form.
At a basic level, a custom debugger visualizer is just a Windows Forms application that is launched by Visual Studio, with the object being debugged passed as a parameter.
The basic code you need to implement the visualizer is shown below. You will need to get a reference to "Microsoft.VisualStudio.DebuggerVisualizer.dll" which ships with Visual Studio, but you do need to make sure you are using the correct version of this assembly depending on whether you are using Visual Studio 2005 or Visual Studio 2008.
The <Assembly> attribute is used by Visual Studio to associate the Microsoft.Crm.Sdk.DynamicEntity type with the Visualizer, and once compiled, you can simply copy your assembly to the folder "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers\". Visual Studio will automatically use any visualizers it finds in this folder.
To build the user interface, simply create a new Windows Form in the project, add a "SplitContainer" control and place a "TreeView" control on the left side of the split and a "DataGridView" control on the right.
Next, create a "DynamicEntityProperty" class that we can use to store property attribute names and values.
Next we have to implement the logic that iterates through the dynamic entity and populates the "TreeView" control as shown below.
Once we have a "TreeView" with one or more "TreeNode" objects, we have to implement the logic that iterates through the attributes for each individual property, and add them to the TreeNode.Tag property as shown below. To keep the code short, and avoid writing the same For...Next code for each CRM property type, I decided to make use of .NET Reflection within the "AddDynamicEntityPropertyValueToTreeNode" function.
Finally, the last piece of code is needed to update the "DataGridView" by binding data stored in the "TreeNode.Tag" property when selecting a Dynamic Entity property in the "TreeView". We can also take this opportunity to set some properties on the "DataGridView" in order to make the table format look nice.
So there we have it. A really useful piece of functionality that saves time and effort when debugging your plug-ins and custom workflow assemblies. I built this solution in Visual Studio 2008, for debugging in Visual Studio 2008 and you can download the project files here.
If you want to use this "AS IS" you can just copy file "SRH.CRM.VisualStudio.DebuggerVisualizer.dll" from the \bin\debug project folder to the folder "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers\". However, if you do wish to modify the functionality, or re-compile it to run under Visual Studio 2005, then please feel free to do so.
This posting is provided "AS IS" with no warranties, and confers no rights.