« Configuring the CRM 4.0 Outlook client with IFD | Main | SQL Timeout During CRM Version 4.0 Installation »
October 29, 2008
Storing Configuration Data for Plugins
I recently read Mitch Milam's post on the CRM Team blog on passing configur ation data to a plugin. I like his approach and had even have done it a few times prior to the publishing of his article. Lately, though, I've been keen on storing the configuration data not within the plugin configuration, but within custom CRM entities. This makes for a super-slick way of saving configuration information that does not require having to fire up the Plugin Registration Tool (it looks good in demos, also!)
I first took this approach a while back when doing a javascript version of custom auto-incrementing values, but I've started to structure this a little differently. While in that post, I utilized a "catch-all" setting entity, but a better approach might be to utilize a configuration entity for each different kind of configuration. This allows for even more flexibility, in my opinion.
So, taking a look back at the auto-incrementing solution, let's assume we're doing the same thing with a plugin.
Configuration Entity
I originally used three settings for this solution: Prefix, Increment and Pad. Now, I want to add two more: Entity and Attribute. You'll see why in a bit. With that in mind, I'll create an entity named new_autoincrement with the following attributes:
| Attribute | Type | Comments |
| new_entity | nvarchar | Name of the entity that has the attribute to which we'll save the value. |
| new_attribute | nvarchar | Name of the CRM attribute to which we'll save the custom value. |
| new_prefix | nvarchar | Optional prefix for the number. |
| new_increment | int | Next number to assign. |
| new_pad | int | Number of zeros to pad at the beginning of the number. |
Why did I add the entity and attribute settings? Well, with these in place, I can now have the plugin registered against multiple entities and also perform the calculation for multiple attributes on the same record. Once you have the plugin registered against the entity, you can add, modify and remove incrementing attributes just by updating your configuration entity - WITHOUT having to update any plugin code! Pretty neat idea, and it's really easy to have your plugin logic support this functionality.
Plugin Logic
Okay, we've got our custom entity that will store the configuration information. Next we need to write our code to pull the data. This is really straightforward, so I'll just present the basic logic that I use in the Execute method here:
// populate a field with custom incrementing value
try
{
// test the message (create/update/delete)
if (context.MessageName == "Create" && context.Stage == MessageProcessingStage.BeforeMainOperationOutsideTransaction)
{
// grab the target entity
if (context.InputParameters.Properties.Contains("Target") &&
context.InputParameters.Properties["Target"] is DynamicEntity)
{
DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties["Target"];// initialize service
ICrmService oService = context.CreateCrmService(true);
// read configuration info from CRM (new_autoautoincrement entity)
ConditionExpression con = new ConditionExpression();
con.AttributeName = "new_entity";
con.Operator = ConditionOperator.Equal;
con.Values = new string[] { entity.Name };
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.AddCondition(con);
QueryExpression qry = new QueryExpression();
qry.EntityName = "new_autoautoincrement";
qry.ColumnSet = new AllColumns();
qry.Criteria = filter;// execute query
RetrieveMultipleRequest request = new RetrieveMultipleRequest();
request.Query = qry;
request.ReturnDynamicEntities = true;
RetrieveMultipleResponse response = (RetrieveMultipleResponse)oService.Execute(request);if (response.BusinessEntityCollection.BusinessEntities.Count > 0)
{
foreach (DynamicEntity oConfigEntity in response.BusinessEntityCollection.BusinessEntities)
{
// loop through each configuration for the entity
Key kConfigId = (Key)oConfigEntity.Properties["new_autoincrementid"];
string sAttribute = (string)oConfigEntity.Properties["new_attribute"];
// check to see that attribute isn't already populated. if so, skip.
if(entity.Properties.Contains(sAttribute))
{
continue;
}
// ******************************************************************************************// INSERT LOGIC HERE TO BUILD THE NUMBER AND SAVE THE INCREMENTED
// VALUE BACK TO THE CONFIGURATION RECORD
// ******************************************************************************************
}
}
}
}
}
catch (SoapException ex)
{
throw new InvalidPluginExecutionException("An error occurred in the Autoincrement plug-in: " + ex.Message, ex);
}
The above snippet grabs each configuration record for the entity for which the plugin is registered. if there are no configurations entered, the plugin will simply not do anything and exit happily. If there are numerous configurations entered, then it will process each one (this is a really nice trick). Should you decide to use this exact code, you'll need to complete the logic to actually build the number and save your new Increment value back to CRM.
Wrap-Up
So, while it may seem like there's some additional overhead in having to set up a custom entity, then query that entity, etc, I think the added flexibility and firepower your solution now has is well worth the added effort. This also lets you keep the code generic, which is invaluable when developing in one environment and deploying to many other environments where you may be implementing for different entities and/or attributes across those environments - you can keep a single code base.
Posted by Will Wilson on October 29, 2008 at 09:25 PM in Microsoft CRM Customizations | Permalink
TrackBack
TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00e54fb34b6f8833010535c98476970c
Listed below are links to weblogs that reference Storing Configuration Data for Plugins:
Comments
Verify your Comment
Previewing your Comment
Posted by: |
This is only a preview. Your comment has not yet been posted.
The letters and numbers you entered did not match the image. Please try again.
As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.
Having trouble reading this image? View an alternate.




Good article Will. I actually have a secondary article in the pipeline that will explore using a custom entity in a similar manner to what you described but using it to hold the XML configuration information as shown in my first article.
Thanks, Mitch
Posted by: Mitch Milam | November 06, 2008 at 09:26 AM
Thanks, Mitch. I actually like the idea of storing the raw config xml in an entity - it offers up a different degree of flexibility.
Posted by: Will Wilson | November 14, 2008 at 04:58 PM