Building XrmToolBox Tools
I have some catching up to do! I am finally posting about my recent presentation at the DC CRMUG Chapter Meeting. In this post, I provide a quick overview of the presentation and cover some of the base concepts in building an XrmToolBox tool. You can download a copy of my slides from the presentation here: Building XrmToolBox Tools
But first, some cool stuff has been happening in the Dynamics community in recent weeks…
Cool Community Stuff
Jonas Rapp recently presented a session at 365 Saturday Stockholm called “Let’s build an XrmToolBox tool!” During his talk, he used one of my shared controls (yeah!) combined with his killer Grid control to build an XrmToolBox tool from scratch based on feedback from the attendees. (Seriously cool idea for a talk!) I spoke a few days later at the DC CRMUG Chapter Meeting on a similar topic, though I came prepared with a tool already framed out. I was not quite as adventurous as Jonas in building a tool on the spot, but the talk went well and I hope it provided a nice introduction to building XrmToolBox Tools.
The demo Tool we discussed allowed users to select a Security Role in Dynamics CRM and view the list of System Users that have that role assignment. During the talk, Kylie Kiser mentioned her method for managing users using Advanced Find and posted about it last week titled “Managing Users in Dynamics 365“. As usual, an excellent post from Kylie as she shares solid methods for managing Dynamics CRM. And just this week, Michael Ochs released his own XrmToolBox Tool, “Dynamics 365 Universal Search for XrmToolBox“. When creating his new Tool, Michael leveraged shared controls built by both Jonas and myself and it sounds like it saved him a bit of time.
It’s really cool to see something you’ve built in action and exciting to see ideas shared and developed by the community!
Building XrmToolBox Tools Overview
The first portion of my Building XrmToolBox Tools presentation included a brief overview of the XrmToolBox, some thoughts on who might use the application, some examples of Tools that benefit different audiences. I’ll skip over this section for now, assuming most readers are familiar with the XrmToolBox, and for some examples, I’ll refer to my series of posts about useful XrmToolBox tools: Some Useful XrmToolbox Plugins, More Useful XrmToolbox Plugins, and And even MORE Useful XrmToolbox plugins!
The next portion of the presentation digs into what comprises a Tool, formerly referred to as a Plugin. Even if you are familiar with the XrmToolBox application, you may not be too familiar with the building blocks of an individual Tool. This discussion is usually directed towards developers, but I don’t think you need to be a developer to understand how the XrmToolBox application interacts with its Tools!
An XrmToolBox Tool is .NET component hosted by the XrmToolBox application implementing a shared programmatic contract. By implementing this shared contract, the XrmToolBox application can load multiple Tool and present common information about each Tool in the shared user interface. Once loaded, the XrmToolBox application can further interact with each Tool using agreed upon methods and properties. Once loaded, the XrmToolBox application. For example, the XrmToolBox application can provide the CRM instance connection information to the tool and notify the Tool if the connection changes. The Tool can then interact with the parent XrmToolBox application by displaying messages to users in the common notification area or displaying a message banner for long running operations.
Building Blocks of a Tool
From a developers perspective, each XrmToolBox Tool is comprised of two primary classes: a Plugin and PluginControl class. These classes come in pairs for each tool, the first being a standard C# class implementing a few properties and methods, while the second is a C# class deriving from the .NET WinForm UserControl. So in the sample application we discussed at our CRMUG meeting, I had two components named
MyPluginControl. In a real situation, you might name your classes
SecurityRoleAssignmentControl. Implement these two components and you have an XrmToolBox Tool! XrmToolBox application provide some extensible building blocks through some base classes that provide developers with an excellent foundation in building new Tools.
Your Plugin Class will contain the public details behind your XrmToolBox Tool, and the XrmToolBox references provide the
PluginBase class from which you can inherit some basic functionality. Your Plugin will surface public details such as the Tool name, description, and the large and small icons. This is implemented through C# attributes that the XrmToolBox application will retrieve on load of your Tool. With the sample Tool example, we could name our new Plugin class
SecurityRoleAssignment and our Attributes would be:
ExportMetadata("Name", "Sample Security Role Assignment Viewer XrmToolBox Tool")
ExportMetadata("Description", "View which users have a Security Role assignment")
This class will also provide the method for loading and displaying your PluginControl component. The only real code in this class is usually overriding the
GetControl() method that returns an instance of your PluginControl component, but it is the foundation for your new Tool.
Once the Plugin class is loaded, the XrmToolBox application will load your user control, or your PluginControl class, using the the
GetControl() method described above. Although the Plugin Class is the baseline needed to load your Tool, the PluginControl class is where the bulk of your Tool work will happen. This means retrieving information from Dynamics CRM, rendering user interface elements, and applying business logic for your XrmToolBox Tool.
Just like the Plugin class, the XrmToolBox references include a base class called the
PluginControlBase that provides a significant set of functionality for your tool. The
PluginControlBase base class first derives from the WinForm UserControl class, and provides common methods and properties for two way communication between your Tool and XrmToolBox:
Service – access to the current
OrganizationServiceconnection provided by the parent XrmToolBox application
WorkAsync – a common method for performing long running operations asynchronously to avoid locking up the XrmToolBox user interface
Update Connection – allows the Tool to be notified when the connection changes in the parent XrmToolBox application
Settings – a common method for persisting Tool specific settings
Logging – a common method for logging tracing or exceptions for your Tool
Notifications – a common set of methods for displaying user notifications in the parent XrmToolBox notification area
Keeping with the Plugin class example, we would name this PluginControl class
SecurityRoleAssignmentControl and it would be loaded up by our
SecurityRoleAssignment class. Once our
SecurityRoleAssignmentControl component loads, it’s up to us to start providing the our Tool functionality to the user!
Listening to the recent XrmToolCast Episode 1, I learned that these base classes were a contribution by Daryl LaBar. This is an important contribution because a base classes provide not only shared functionality to make things easier on developers, it provides a shared standard for developing Tools for the XrmToolBox. Daryl has some very cool Tools of his own. If you have not already used this one, be sure to check out his extremely useful Tool, the Attribute Manager. This can save you LOADS of time!
The XrmToolBox components include an additional base class called the
MultipleConnectionsPluginControlBase meant for Tools that require more than one service endpoint connection. For example, a Tool might allow transfer of data from one environment to another. I plan on a follow up post with more detail on using this base class.
In the next post, we will take a look at the details of the sample XrmToolBox Tool that we reviewed during class. We will take a look at the Visual Studio Template provided by the XrmToolBox team, some shared controls available that save some development time, and how to test your tool during development.
As always, comments and corrections are welcome!